📄 secedit.pas
字号:
TreeView.FCloseOnUp := True;
FOriginalNode := TreeView.Selected;
FOriginalText:= Text;
FSelectedNode:= FOriginalNode;
inherited;
if Style = csDropDownList then
Invalidate;
Update;
Selectall;
end;
function TSecCustomTreeCombo.GetDropDownContainer: TWinControl;
begin
result:=FPanel;
end;
function TSecCustomTreeCombo.GetDropDownControl: TWinControl;
begin
result:=TreeView;
end;
function TSecCustomTreeCombo.GetItemCount: Integer;
begin
result:=Items.Count;
end;
function TSecCustomTreeCombo.GetItems: TTreeNodes;
begin
result:=FTreeView.Items;
end;
function TSecCustomTreeCombo.GetItemSize: TSize;
var
Node:TTreeNode;
function LargestRect: TSize;
var
Node: TTreeNode;
i: Integer;
begin
result.cx:=0;
result.cy:=0;
Node := TreeView.Items.GetFirstNode;
while Node <> nil do
begin
with Node.DisplayRect(True) do
begin
TreeView.Canvas.Font:= TreeView.Font;
i:= Left + TreeView.Canvas.TextWidth(Node.Text) + 6;
if (Node.ImageIndex=-2) and (TreeView.Images<>nil) then
inc(i, TImageList(TreeView.Images).Width);
result.cy := Bottom - Top;
end;
if i > result.cx then
result.cx := i;
Node := Node.GetNextVisible;
end;
end;
begin
if DropDownWidth=0 then
begin
Node := Items.GetFirstNode;
if Node <> nil then
result := LargestRect
else
begin
result.cx:=0;
result.cy:=0;
end;
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
begin
result.cx:=0;
result.cy:=0;
end;
end;
end;
function TSecCustomTreeCombo.IsDroppedDown: Boolean;
begin
result := FPanel.Visible;
end;
function TSecCustomTreeCombo.IsValidNode(Node: TTreeNode): Boolean;
begin
result:= TreeView.ValidNode(Node);
if Assigned(OnCheckValidItem) then
OnCheckValidItem(Self, Node, result);
end;
procedure TSecCustomTreeCombo.SetDropDownWidth(const Value: integer);
begin
FDropDownWidth := Value;
end;
procedure TSecCustomTreeCombo.SetItems(const Value: TTreeNodes);
begin
FTreeView.Items:=Value;
end;
procedure TSecCustomTreeCombo.SetOnCheckValidItem(
const Value: TSecCheckValidItemEvent);
begin
FOnCheckValidItem := Value;
end;
{ TSecPanel }
constructor TSecPanel.Create(AOwner: TComponent);
begin
inherited;
ControlStyle := ControlStyle + [csNoDesignVisible, csReflector, csReplicatable];
BevelInner := bvNone;
BevelOuter := bvNone;
Height := 100;
OnContextPopup:=DoMeContextPopup;
end;
procedure TSecPanel.CreateParams(var Params: TCreateParams);
begin
inherited;
with Params do
begin
Style := WS_POPUP or WS_BORDER;
ExStyle := WS_EX_TOOLWINDOW;
WindowClass.Style := CS_SAVEBITS;
end;
end;
procedure TSecPanel.DoMeContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
begin
Handled:=true;
end;
{ TSecPopupTreeView }
constructor TSecPopupTreeView.Create(AOwner: TComponent);
begin
inherited;
ControlStyle := ControlStyle - [csCaptureMouse] + [csDisplayDragImage, csReflector]
+ [csReplicatable];
FCloseOnUp := True;
end;
function TSecPopupTreeView.GetItemHeight: ShortInt;
begin
result := TreeView_GetItemHeight(Handle);
end;
function TSecPopupTreeView.GetLastNode: TTreeNode;
var
Node: TTreeNode;
begin
result := nil;
Node := Items.GetFirstNode;
while Node <> nil do
begin
result := Node;
Node := Node.GetNext;
end;
end;
function TSecPopupTreeView.GetLastVisible: TTreeNode;
var
Node: TTreeNode;
begin
result := nil;
Node := Items.GetFirstNode;
while Node <> nil do
begin
result := Node;
Node := Node.GetNextVisible;
end;
end;
procedure TSecPopupTreeView.KillTimer;
begin
if HandleAllocated then
Windows.KillTimer(Handle, SECPOPUPTIMERID);
FTimerOn := False;
end;
procedure TSecPopupTreeView.MouseMove(Shift: TShiftState; X, Y: Integer);
var
Node:TTreeNode;
p:TPoint;
Msg: TWMTimer;
flag:Boolean;
Rect: TRect;
begin
inherited;
Node := GetNodeAt(X, Y);
flag:=TreeCombo.IsValidNode(Node);
if (Node <> nil) and flag then
begin
Selected := Node;
TreeView_GetItemRect(Node.Handle, Node.ItemId, Rect, True);
canvas.Brush.Color:=clMenuHighlight;
canvas.FillRect(Rect);
canvas.Font.Color:=clwindow;
canvas.TextOut(Rect.Left+2,Rect.Top+1,Node.Text);
end;
if (TreeCombo <> nil) and (GetKeyState(VK_LBUTTON) < 0) then
begin
GetCursorPos(p);
with ClientToScreen(Point(0, 0)) do
begin
FillChar(Msg, SizeOf(Msg), 0);
if (p.y < y - TreeCombo.Height) or (p.y > y + Height) then
begin
WMTimer(Msg);
SetTimer;
end;
end;
end;
end;
procedure TSecPopupTreeView.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
ClickedNode: TTreeNode;
begin
if (TreeCombo <> nil) and (Button = mbLeft) and FCloseOnUp then
begin
ClickedNode:= GetNodeAt(X, Y);
if (ClickedNode<>nil) and TreeCombo.IsValidNode(ClickedNode) then
begin
TreeCombo.FSelectedNode:= Selected;
TreeCombo.CloseUp(PtInRect(ClientRect, Point(X, Y)));
end;
end;
KillTimer;
FCloseOnUp := True;
end;
function TSecPopupTreeView.MovePage(Node: TTreeNode;
Down: Boolean): TTreeNode;
var
ItemsPerPage: Integer;
i: Integer;
begin
result := nil;
ItemsPerPage := (Height div ItemHeight) + 1;
for i := 0 to ItemsPerPage - 1 do
begin
if Node = nil then
Break;
result := Node;
if Down then
Node := Node.GetNextVisible
else
Node := Node.GetPrevVisible;
end;
if Node <> nil then
result := Node;
end;
function TSecPopupTreeView.SelectValidNode(StartingNode,
SelectedNode: TTreeNode; Key: Word): Boolean;
begin
result := False;
if StartingNode = nil then
begin
StartingNode := Items.GetFirstNode;
if not (Key in [VK_NEXT, VK_END]) then Key := 0;
end;
if (SelectedNode <> nil) and (SelectedNode = Selected) then
begin
Selected := StartingNode;
Exit;
end;
if SelectedNode = nil then
SelectedNode := StartingNode;
if (TreeCombo.isDroppedDown) then
begin
case Key of
VK_UP: SelectedNode := SelectedNode.GetPrevVisible;
VK_DOWN: SelectedNode := SelectedNode.GetNextVisible;
VK_PRIOR: SelectedNode := MovePage(SelectedNode, False);
VK_NEXT: SelectedNode := MovePage(SelectedNode, True);
VK_HOME: SelectedNode := Items.GetFirstNode;
VK_END: SelectedNode := GetLastVisible;
end;
end
else
begin
case Key of
VK_UP: SelectedNode := SelectedNode.GetPrev;
VK_DOWN: SelectedNode := SelectedNode.GetNext;
VK_PRIOR: SelectedNode := MovePage(SelectedNode, False);
VK_NEXT: SelectedNode := MovePage(SelectedNode, True);
VK_HOME: SelectedNode := Items.GetFirstNode;
VK_END: SelectedNode := GetLastNode;
end;
end;
if SelectedNode = nil then
Exit;
if not TreeCombo.IsValidNode(SelectedNode) then
begin
if Key in [VK_UP, VK_PRIOR, VK_END] then
Key := VK_UP
else
Key := VK_DOWN;
SelectValidNode(StartingNode, SelectedNode, Key);
end
else
Selected := SelectedNode;
result := True;
end;
procedure TSecPopupTreeView.SetItemHeight(const Value: ShortInt);
begin
TreeView_SetItemHeight(Handle, Value);
end;
procedure TSecPopupTreeView.SetTimer;
begin
Windows.SetTimer(Handle, SECPOPUPTIMERID, SECPOPUPINTERVAL, nil);
FTimerOn := True;
end;
function TSecPopupTreeView.ValidNode(Node: TTreeNode): Boolean;
begin
if (TreeCombo <> nil) {and (icoEndNodesOnly in TreeCombo.Options)} then
result := Node.Count = 0
else
result := True;
//if not Node.Selected then
//result := False;
end;
procedure TSecPopupTreeView.WMLButtonDown(var Message: TWMLButtonDown);
begin
FClickedInControl:=true;
if TreeCombo <> nil then
TreeCombo.CheckCancelMode;
FCloseOnUp := False;
if PtInRect(Rect(0, 0, ClientWidth, ClientHeight), Point(Message.XPos, Message.YPos)) then
FCloseOnUp := True;
end;
procedure TSecPopupTreeView.WMMouseActivate(var Message: TMessage);
begin
Message.Result := MA_NOACTIVATE;
end;
procedure TSecPopupTreeView.WMNCHitTest(var Message: TWMNCHitTest);
begin
DefaultHandler(Message);
end;
procedure TSecPopupTreeView.WMTimer(var Message: TWMTimer);
var
p: TPoint;
begin
inherited;
if GetKeyState(VK_LBUTTON) >= 0 then
begin
if TreeCombo <> nil then
TreeCombo.CloseUp(True);
Exit;
end;
if Selected = nil then
Exit;
GetCursorPos(p);
with ClientToScreen(Point(0, 0)) do
begin
if p.y < y then
SelectValidNode(Selected, nil, VK_UP)
else if p.y > y + Height then
SelectValidNode(Selected, nil, VK_DOWN);
end;
end;
procedure TSecPopupTreeView.WndProc(var Message: TMessage);
begin
case Message.Msg of
WM_LBUTTONDBLCLK, WM_RBUTTONDOWN, WM_RBUTTONDBLCLK: ;
else
inherited;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -