📄 fctreecombo.pas
字号:
var Node: TfcTreeNode;
begin
if DropDownWidth=0 then
begin
Node := Items.GetFirstNode;
if Node <> nil then result := LargestRect
else result := fcSize(0, 0);
end
else begin
Node := Items.GetFirstNode;
if Node <> nil then begin
result.cx:= DropDownWidth;
with Node.DisplayRect(True) do
result.cy:= Bottom-Top
end
else result := fcSize(0, 0);
end;
end;
procedure TfcCustomTreeCombo.CMTextChanged(var Message: TMessage);
begin
inherited;
end;
procedure TfcCustomTreeCombo.DropDown;
begin
// 2/25/99 - Make certain that combo does not dropdown if datasource is not enabled.
if (Datalink.field=nil) and ((datasource<>nil) or (datafield<>'')) then exit;
// ControlStyle := ControlStyle - [csNoDesignVisible];
TreeView.FLastPoint := Point(-1, -1);
TreeView.FClickedInControl := False;
TreeView.FCloseOnUp := True;
ResyncTreeSelected(Text); { Move earlier }
FOriginalNode := TreeView.Selected;
FOriginalText:= Text;
FSelectedNode:= FOriginalNode; { RSW }
if icoExpanded in Options then begin
TreeView.FullExpand;
if ((Text='') or (FSelectedNode=nil)) and (TreeView.Items.GetFirstNode<>nil) then
begin
{ 4/5/99 - Default to top of tree. Don't use TopItem here as it has strange horizontal scrolling behavior}
TreeView.selected:= TreeView.Items.GetFirstNode;
TreeView.Selected:= nil;
end
else if FSelectedNode<>Nil then FSelectedNode.MakeVisible;
end;
if Style = csDropDownList then Invalidate;
inherited;
//2/25/99 - Removed from fcCombo so needs to be added here.
Update;
Selectall;
// SetScrollPos(TreeView.Handle, sb_horz, 50, True);
end;
procedure TfcCustomTreeCombo.CloseUp(Accept: Boolean);
var IsDroppedDown: Boolean;
begin
// ControlStyle := ControlStyle + [csNoDesignVisible];
IsDroppedDown := self.IsDroppedDown;
inherited;
if IsDroppedDown then
begin
if Accept and (FOriginalNode<>FSelectedNode) and EditCanModify then { RSW }
begin
SelectionChanging;
if FSelectedNode<>nil then begin
SetModifiedInChangeEvent:=true;
Text:= FSelectedNode.Text; { RSW }
SetModifiedInChangeEvent:=False;
end;
// if TreeView.Selected <> nil then Text := TreeView.Selected.Text;
SelectionChange;
SetModified(True);
end else begin
TreeView.Selected := FOriginalNode;
if TreeView.Selected <> nil then Text := TreeView.Selected.Text
else Text:= FOriginalText; // if not fcIsInwwGrid(self) then Text := '';
end;
DoCloseUp(Accept);
end;
TreeView.KillTimer;
if Editable then SelectAll; //(Style = csDropDown) then SelectAll;
end;
procedure TfcCustomTreeCombo.SetSelectedNode(Node:TfcTreeNode);
begin
inherited;
FSelectedNode := Node;
end;
function TfcCustomTreeCombo.IsDroppedDown: Boolean;
begin
result := FPanel.Visible;
end;
procedure TfcCustomTreeCombo.DrawInGridCell(ACanvas: TCanvas; Rect: TRect;
State: TGridDrawState);
begin
PaintToCanvas(ACanvas, Rect, (gdSelected in State), True, DataLink.Field.Text);
end;
procedure TfcCustomTreeCombo.CreateWnd;
begin
inherited;
FPanel.Parent := self;
end;
procedure TfcCustomTreeCombo.KeyUp(var Key: WORD; Shift: TShiftState);
begin
inherited;
{ if EffectiveReadOnly then Exit; // Prevent selection change with keyboard when readonly
case Key of
VK_BACK:
if (Style=csDropDownList) and (not isDroppedDown) then
begin
key:= 0;
end;
end;}
end;
procedure TfcCustomTreeCombo.KeyDown(var Key: WORD; Shift: TShiftState);
var r: TRect;
begin
inherited;
if EffectiveReadOnly then Exit; // Prevent selection change with keyboard when readonly
case Key of
VK_BACK, VK_DELETE:
if (Style=csDropDownList) {and (not isDroppedDown) }then
begin
//4/27/99 - Handle BackSpace Key as well.
if (AllowClearKey) and
((selText=Text) or
(not IsDroppedDown) and ((key=vk_delete) or ((key=vk_back) and (not ShowMatchText)))) then
begin
SelectionChanging;
Text:= '';
TreeView.Selected := nil;
// SelectionChange;
TreeView.FCheckChange := False;
SetModified(True);
key:= 0;
end
else begin
if (selStart>0) and ShowMatchText then
begin
SendMessage(Handle, EM_SETSEL, length(Text), selStart-1);
SendMessage(Handle, EM_SCROLLCARET, 0,0);
end;
key:= 0;
end;
end;
VK_UP, VK_DOWN, VK_HOME, VK_END, VK_PRIOR, VK_NEXT:
begin
if (Key in [VK_HOME, VK_END]) and not (ssCtrl in Shift) and IsDroppedDown then Exit;
if Items.Count > 0 then
if (Style = csDropDownList) or (((Key = VK_UP) or (Key = VK_DOWN)) and not IsDroppedDown) then
begin
SelectionChanging;
if not TreeView.SelectValidNode(TreeView.Selected, nil, Key) then
begin
r := GetEditRect;
InvalidateRect(Handle, @r, False);
end;
SelectionChange;
SetModified(True);
Key := 0;
end else if IsDroppedDown then begin
SelectionChanging;
TreeView.SelectValidNode(TreeView.Selected, nil, Key);
SelectionChange;
Key := 0;
end;
SelectAll;
end;
end;
end;
procedure TfcCustomTreeCombo.WndProc(var Message: TMessage);
begin
inherited;
end;
procedure TfcCustomTreeCombo.KeyPress(var Key: Char);
// This method occurs before the text has changed on the edit, so
// this method returns what the text will be after the key has been
// processed.
function NewText: string;
var CurStr: string;
begin
CurStr:= Text;
result:= Copy(CurStr, 1, SelStart) + Char(Key) +
Copy(CurStr, SelStart + 1 + Length(SelText), 32767);
end;
var Text: string;
// Return the first node whose beginning text matches the current
// text of the combo.
function FindNode: TfcTreeNode;
var InitialNode: TfcTreeNode;
begin
InitialNode := TreeView.Selected;
if InitialNode.Index < GetStartingNode.Index then InitialNode := GetStartingNode;
result := InitialNode;
repeat
if IsValidNode(result) and (UpperCase(Copy(result.Text, 1, Length(Text))) = UpperCase(Text)) then Exit;
result := result.GetNext;
if result = nil then result := GetStartingNode;
until result = InitialNode;
result := nil;
end;
var Node: TfcTreeNode;
TextLen: Integer;
HaveChangedText: boolean;
begin
inherited;
TreeView.HandleNeeded; { Allows Items to be valid }
if (key=#8) and (Style=csDropDownList) and ShowMatchText then
begin
key:= #0;
if key=#0 then exit;
end;
if (Items.Count > 0) and (key<>#0) and
(IsDroppedDown or (ShowMatchText {and (Style = csDropDown)})) and not (Key in [#8]) then
begin
// 3/15/2002 - Don't get new text if user hit Return/Enter key as this messes up Storedatausing path.
if Key <> #13 then Text := NewText;
Node := FindNode;
if Node <> nil then
begin
TreeView.Selected := Node;
FSelectedNode:= Node; { RSW }
// Quicken-style highlighting
if ShowMatchText then
begin
HaveChangedText:= self.text<>node.text;
self.Text := Node.Text;
TextLen := Length(Text);
SelStart := Length(Node.Text);
SelLength := - (Length(Node.Text) - TextLen);
end else begin
HaveChangedText:= self.text<>node.text;
self.Text := Text;
SelStart := Length(Text);
end;
// TreeView.Selected := Node; { 4/22/99 RSW - Already set so redundant }
if HaveChangedText then
begin
SelectionChange; { 4/22/99 - RSW }
SetModified(True);
end;
Key := #0;
end else begin
// if IsDroppedDown and (Style = csDropDownList) then Key := #0 // If selection is not in list, but dropped down, then don't allow invalid entries
if (Style = csDropDownList) then Key := #0 // If selection is not in list, but dropped down, then don't allow invalid entries
else begin
TreeView.Selected := nil; //4/27/99 - Clear selection only if dropdown style and not found.
FSelectedNode:= Nil; { 11/17/99 - Clear selected so you can type
in things not in the list when it is dropped down}
end;
end;
end;
{ if (key=#8) and (Style=csDropDownList) then
begin
if (not isDroppedDown) then key:= #0
else if Text=SelText then key:= #0
end;
}
if (Key<>#0) and (Style=csDropDown) then SetModified(True) { RSW };
if Key = #13 then Key := #0;
end;
procedure TfcCustomTreeCombo.Loaded;
begin
inherited;
if Sorted then TreeView.AlphaSort;
end;
procedure TfcCustomTreeCombo.Paint;
begin
with ClientRect do PaintToCanvas(Canvas, Rect(0, 0, Right - Left, Bottom - Top), True, False, Text);
end;
function TfcCustomTreeCombo.GetLeftIndent: Integer;
begin
result := inherited GetLeftIndent + 1;
if fcIsInwwGrid(self) then Result:= Result -1; { 7/5/99 }
if (Images <> nil) then inc(result, TImageList(Images).Width + 2);
end;
function TfcCustomTreeCombo.GetEditRect: TRect;
begin
result:= inherited GetEditRect;
if result.Right<=result.Left+10 then
result.Right:= result.Left + 10; // 5/3/99 - RSW - Ensure edit rectangle is at least 10 pixels wide
end;
function TfcCustomTreeCombo.Editable: Boolean;
begin
Result := (Style <> csDropDownList) or isDroppedDown or ShowMatchText;
end;
function TfcCustomTreeCombo.IsValidNode(Node: TfcTreeNode): Boolean;
begin
result:= TreeView.ValidNode(Node);
if Assigned(OnCheckValidItem) then OnCheckValidItem(Self, Node, result);
end;
procedure TfcCustomTreeCombo.HideCaret;
begin
if (not showMatchText) then inherited;
end;
procedure TfcCustomTreeCombo.UpdateData(Sender: TObject);
var s: string;
begin
if StoreDataUsing =sdStoreText then
s:= Text
else if StoreDataUsing = sdStoreData1 then
begin
if SelectedNode=nil then s:= ''
else s:= SelectedNode.StringData;
end
else begin
if SelectedNode=nil then s:= ''
else s:= SelectedNode.StringData2
end;
if DataLink.Field.Text <> s then
DataLink.Field.Text := s;
end;
procedure TfcCustomTreeCombo.DataChange(Sender: TObject);
var TempNode: TfcTreeNode;
begin
if DataLink.Field <> nil then
begin
if not (csDesigning in ComponentState) then
begin
if (DataLink.Field.DataType = ftString) and (MaxLength = 0) then
MaxLength := DataLink.Field.Size;
end;
if Focused and DataLink.CanModify then
begin
if StoreDataUsing =sdStoreText then
Text := DataLink.Field.Text
else begin
tempNode := TreeView.Items.FindNodeInfo(
DataLink.Field.Text, False, StoreDataUsing);
if tempNode<>nil then
Text:= tempNode.Text
else Text:=DataLink.Field.Text;
end
end
else begin
if StoreDataUsing =sdStoreText then
Text := DataLink.Field.DisplayText
else begin
tempNode := TreeView.Items.FindNodeInfo(
DataLink.Field.Text, False, StoreDataUsing);
if tempNode<>nil then
Text:= tempNode.Text
else Text:=DataLink.Field.Text;
end
end;
end
else begin
if csDesigning in ComponentState then
Text := Name
else
Text := '';
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -