📄 jvcombobox.pas
字号:
if InvokeOrgRender then
begin
Canvas.FillRect(Rect);
if (Index >= 0) and (Index <= Items.Count) then
Canvas.TextOut(Rect.Left + 2, Rect.Top, GetItemText(Index));
end;
end;
end;
function TJvCustomComboBox.GetItemCount: Integer;
var
VL: IJvDataConsumerViewList;
begin
if IsProviderSelected then
begin
Provider.Enter;
try
if Supports(Provider as IJvDataConsumer, IJvDataConsumerViewList, VL) then
Result := VL.Count
else
Result := 0;
finally
Provider.Leave;
end;
end
else
{$IFDEF COMPILER6_UP}
Result := inherited GetItemCount;
{$ELSE}
Result := Items.Count;
{$ENDIF COMPILER6_UP}
end;
{$IFDEF COMPILER6_UP}
function TJvCustomComboBox.GetItemsClass: TCustomComboBoxStringsClass;
begin
Result := TJvComboBoxStrings;
end;
{$ENDIF COMPILER6_UP}
function TJvCustomComboBox.GetItemText(Index: Integer): string;
var
VL: IJvDataConsumerViewList;
Item: IJvDataItem;
ItemText: IJvDataItemText;
begin
if IsProviderSelected then
begin
if Supports(Provider as IJvDataConsumer, IJvDataConsumerViewList, VL) then
begin
Provider.Enter;
try
if (Index >= 0) and (Index < VL.Count) then
begin
Item := VL.Item(Index);
if Supports(Item, IJvDataItemText, ItemText) then
Result := ItemText.Caption
else
Result := RsDataItemRenderHasNoText;
end
else
TJvComboBoxStrings(Items).Error(SListIndexError, Index);
finally
Provider.Leave;
end;
end
else
Result := '';
// TJvComboBoxStrings(Items).Error(SListIndexError, Index);
end
else
Result := Items[Index];
end;
function TJvCustomComboBox.GetMeasureStyle: TJvComboBoxMeasureStyle;
begin
Result := FMeasureStyle;
end;
function TJvCustomComboBox.GetText: TCaption;
begin
if FIsEmptyValue then
Result := ''
else
Result := inherited Text;
end;
function TJvCustomComboBox.HandleFindString(StartIndex: Integer; Value: string;
ExactMatch: Boolean): Integer;
var
VL: IJvDataConsumerViewList;
HasLooped: Boolean;
Item: IJvDataItem;
ItemText: IJvDataItemText;
begin
if IsProviderSelected and
Supports(Provider as IJvDataConsumer, IJvDataConsumerViewList, VL) then
begin
Provider.Enter;
try
HasLooped := False;
Result := StartIndex + 1;
while True do
begin
Item := VL.Item(Result);
if Supports(Item, IJvDataItemText, ItemText) then
begin
if ExactMatch then
begin
if AnsiSameText(Value, ItemText.Caption) then
Break;
end
else
if AnsiStrLIComp(PChar(Value), PChar(ItemText.Caption), Length(Value)) = 0 then
Break;
end;
Inc(Result);
if Result >= VL.Count then
begin
Result := 0;
HasLooped := True;
end;
if (Result > StartIndex) and HasLooped then
begin
Result := -1;
Exit;
end;
end;
finally
Provider.Leave;
end;
end
else
Result := -1;
end;
function TJvCustomComboBox.IsProviderSelected: Boolean;
begin
Result := FProviderIsActive;
end;
procedure TJvCustomComboBox.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
FKey := Key;
end;
{$IFDEF COMPILER5}
procedure TJvCustomComboBox.DoChange(Sender: TObject);
begin
Change;
end;
procedure TJvCustomComboBox.DoDropDown(Sender: TObject);
begin
if AutoDropDown and DroppedDown then
DroppedDown := False;
end;
procedure TJvCustomComboBox.DoValueChange(Sender: TObject);
begin
Click;
Select;
end;
procedure TJvCustomComboBox.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
if AutoComplete then
FAutoCompleteCode.AutoComplete(Key);
end;
procedure TJvCustomComboBox.Select;
begin
if Assigned(FOnSelect) then
FOnSelect(Self)
else
Change;
end;
{$ENDIF COMPILER5}
procedure TJvCustomComboBox.Loaded;
begin
inherited Loaded;
RecreateWnd; // Force measuring at the correct moment
end;
procedure TJvCustomComboBox.MaxPixelChanged(Sender: TObject);
var
St: string;
begin
if Style <> csDropDownList then
begin
St := Text;
FMaxPixel.Test(St, Font);
if Text <> St then
Text := St;
SelStart := Length(Text);
end;
end;
procedure TJvCustomComboBox.MeasureItem(Index: Integer; var Height: Integer);
begin
if not (csLoading in ComponentState) and
(MeasureStyle = cmsStandard) and not IsProviderSelected then
PerformMeasureItem(Index, Height);
end;
procedure TJvCustomComboBox.PerformMeasure;
var
MaxCnt: Integer;
Index: Integer;
NewHeight: Integer;
begin
if FIsFixedHeight then
MaxCnt := 0
else
MaxCnt := GetItemCount - 1;
for Index := -1 to MaxCnt do
begin
NewHeight := FLastSetItemHeight;
PerformMeasureItem(Index, NewHeight);
Perform(CB_SETITEMHEIGHT, Index, NewHeight);
end;
end;
procedure TJvCustomComboBox.PerformMeasureItem(Index: Integer; var Height: Integer);
var
TmpSize: TSize;
VL: IJvDataConsumerViewList;
Item: IJvDataItem;
ItemsRenderer: IJvDataItemsRenderer;
ItemRenderer: IJvDataItemRenderer;
begin
if Assigned(OnMeasureItem) and (Style in [csOwnerDrawFixed, csOwnerDrawVariable]) then
OnMeasureItem(Self, Index, Height)
else
begin
TmpSize.cy := Height;
if IsProviderSelected then
begin
Provider.Enter;
try
if ((Index = -1) or IsFixedHeight or not HandleAllocated) and
Supports(Provider.ProviderIntf, IJvDataItemsRenderer, ItemsRenderer) then
TmpSize := ItemsRenderer.AvgItemSize(Canvas)
else
if (Index <> -1) and not IsFixedHeight and HandleAllocated then
begin
if Supports(Provider as IJvDataConsumer, IJvDataConsumerViewList, VL) then
begin
Item := VL.Item(Index);
if Supports(Item, IJvDataItemRenderer, ItemRenderer) then
TmpSize := ItemRenderer.Measure(Canvas)
else
if DP_FindItemsRenderer(Item, ItemsRenderer) then
TmpSize := ItemsRenderer.MeasureItem(Canvas, Item);
end;
end;
if TmpSize.cy > Height then
Height := TmpSize.cy;
finally
Provider.Leave;
end;
end;
end;
end;
function TJvCustomComboBox.SearchExactString(Value: string;
CaseSensitive: Boolean): Integer;
begin
Result := TJvItemsSearchs.SearchExactString(Items, Value, CaseSensitive);
end;
function TJvCustomComboBox.SearchPrefix(Value: string;
CaseSensitive: Boolean): Integer;
begin
Result := TJvItemsSearchs.SearchPrefix(Items, Value, CaseSensitive);
end;
function TJvCustomComboBox.SearchSubString(Value: string;
CaseSensitive: Boolean): Integer;
begin
Result := TJvItemsSearchs.SearchSubString(Items, Value, CaseSensitive);
end;
procedure TJvCustomComboBox.SetConsumerService(Value: TJvDataConsumer);
begin
end;
procedure TJvCustomComboBox.SetEmptyValue(const Value: string);
begin
FEmptyValue := Value;
if HandleAllocated then
if Focused then
DoEmptyValueEnter
else
DoEmptyValueExit;
end;
procedure TJvCustomComboBox.SetItemHeight(Value: Integer);
begin
FLastSetItemHeight := Value;
{$IFDEF COMPILER6_UP}
inherited SetItemHeight(Value);
{$ELSE}
inherited ItemHeight := Value;
{$ENDIF COMPILER6_UP}
end;
procedure TJvCustomComboBox.SetMeasureStyle(Value: TJvComboBoxMeasureStyle);
begin
if Value <> MeasureStyle then
begin
FMeasureStyle := Value;
RecreateWnd;
end;
end;
procedure TJvCustomComboBox.SetReadOnly(const Value: Boolean);
begin
if FReadOnly <> Value then
begin
FReadOnly := Value;
SendMessage(EditHandle, EM_SETREADONLY, Ord(Value), 0);
end;
end;
procedure TJvCustomComboBox.SetText(const Value: TCaption);
begin
inherited Text := Value;
end;
procedure TJvCustomComboBox.UpdateItemCount;
var
VL: IJvDataConsumerViewList;
Cnt: Integer;
EmptyChr: Char;
begin
if HandleAllocated and IsProviderSelected and
Supports(Provider as IJvDataConsumer, IJvDataConsumerViewList, VL) then
begin
Cnt := VL.Count - SendMessage(Handle, CB_GETCOUNT, 0, 0);
EmptyChr := #0;
while Cnt > 0 do
begin
SendMessage(Handle, CB_ADDSTRING, 0, LParam(@EmptyChr));
Dec(Cnt);
end;
while Cnt < 0 do
begin
SendMessage(Handle, CB_DELETESTRING, 0, 0);
Inc(Cnt);
end;
end;
end;
procedure TJvCustomComboBox.WMInitDialog(var Msg: TWMInitDialog);
begin
inherited;
if (MeasureStyle = cmsAfterCreate) or
(IsProviderSelected and ((MeasureStyle <> cmsBeforeDraw) or FIsFixedHeight)) then
PerformMeasure;
end;
procedure TJvCustomComboBox.WMLButtonDblClk(var Msg: TWMLButtonDblClk);
begin
if not ReadOnly then
inherited;
end;
procedure TJvCustomComboBox.WMLButtonDown(var Msg: TWMLButtonDown);
begin
if ReadOnly then
SetFocus
else
inherited;
end;
procedure TJvCustomComboBox.WndProc(var Msg: TMessage);
begin
if ReadOnly and not (csDesigning in ComponentState) then
begin
case Msg.Msg of
WM_KEYDOWN:
if Msg.WParam in [VK_DOWN, VK_UP, VK_RIGHT, VK_LEFT, VK_F4] then
begin
// (rom) please english comments
// see keelab aktiivse itemi vahetamise nooleklahvidega DDL kui CB on aktiivne
Msg.Result := 0;
Exit;
end;
WM_CHAR:
begin
// DDL trykkides ei aktiveeriks selle tahega algavat itemit
Msg.Result := 0;
Exit;
end;
WM_SYSKEYDOWN:
if (Msg.WParam = VK_DOWN) or (Msg.WParam = VK_UP) then
begin
// see keelab Ald+Down listi avamise fookuses DDL CB-l
Msg.Result := 0;
Exit;
end;
WM_COMMAND:
// DD editis nooleklahviga vahetamise valtimiseks kui fookuses
if HiWord(Msg.WParam) = CBN_SELCHANGE then
begin
Msg.Result := 0;
Exit;
end;
// (rom) these values need an explanation
WM_USER + $B900:
if Msg.WParam = VK_F4 then
begin
// DD F4 ei avaks
Msg.Result := 1;
Exit;
end;
WM_USER + $B904:
if (Msg.WParam = VK_DOWN) or (Msg.WParam = VK_UP) then
begin
// DD Alt+ down ei avaks
Msg.Result := 1;
Exit;
end;
end;
end;
if IsProviderSelected then
case Msg.Msg of
CB_FINDSTRING:
begin
Msg.Result := HandleFindString(Msg.WParam, PChar(Msg.LParam), False);
if Msg.Result < 0 then
Msg.Result := CB_ERR;
Exit;
end;
CB_SELECTSTRING:
begin
Msg.Result := HandleFindString(Msg.WParam, PChar(Msg.LParam), False);
if Msg.Result < 0 then
Msg.Result := CB_ERR
else
Perform(CB_SETCURSEL, Msg.Result, 0);
Exit;
end;
CB_FINDSTRINGEXACT:
begin
Msg.Result := HandleFindString(Msg.WParam, PChar(Msg.LParam), True);
if Msg.Result < 0 then
Msg.Result := CB_ERR;
Exit;
end;
end;
inherited WndProc(Msg);
end;
//=== { TJvPrivForm } ========================================================
function TJvPrivForm.GetValue: Variant;
begin
Result := '';
end;
procedure TJvPrivForm.SetValue(const Value: Variant);
begin
{Nothing}
end;
{$IFDEF UNITVERSIONING}
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -