📄 zproplst.pas
字号:
{$ENDIF}
procedure NodeClicked;
function ButtonHit(X: Integer): Boolean;
procedure SetBorderStyle(Value: TBorderStyle);
function GetFullPropName(Index: Integer): string;
protected
procedure Paint; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure DblClick; override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
function GetPropType: TZPropType;
procedure Edit;
{$IFDEF Delphi6}
function Editor: IProperty;
{$ELSE}
function Editor: TPropertyEditor;
{$ENDIF}
procedure CreateWnd; override;
procedure DestroyWnd; override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure UpdateEditor(CallActivate: Boolean);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure InitCurrent(const PropName: string);
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
procedure CreateParams(var Params: TCreateParams); override;
function VisibleRowCount: Integer;
procedure MarkModified;
procedure ClearModified;
procedure Synchronize;
procedure SetFocus; override;
property CurObj: TObject read FCurObj write SetCurObj;
property Modified: Boolean read FModified;
property RowHeight: Integer read FRowHeight;
property PropCount: Integer read FPropCount;
property InplaceEdit: TZInplaceEdit read FInplaceEdit;
published
property PropColor: TColor read FPropColor write SetPropColor default clNavy;
property IntegralHeight: Boolean read FIntegralHeight
write SetIntegralHeight default False;
property Filter: TTypeKinds read FFilter write SetFilter default tkProperties;
property NewButtons: Boolean read FNewButtons write SetNewButtons
default {$IFDEF Delphi5}True{$ELSE}False{$ENDIF};
property Middle: Integer read FVertLine write SetMiddle default 85;
{$IFDEF Post4}
property ScrollBarStyle: TScrollBarStyle read FScrollBarStyle
write SetScrollBarStyle default ssRegular;
{$ENDIF}
property OnNewObject: TNewObjectEvent read FOnNewObject write FOnNewObject;
{$IFNDEF Delphi2}
property OnHint: THintEvent read FOnHint write FOnHint;
{$ENDIF}
property OnChanging: TChangingEvent read FOnChanging write FOnChanging;
property OnAdvancedChange: TChangeEvent read FOnAdvancedChange write FOnAdvancedChange;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property Align;
property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle;
property Color default clBtnFace;
property Ctl3D;
property Cursor;
property Enabled;
property Font;
property ParentColor default False;
property ParentFont;
property ParentShowHint default False;
property PopupMenu;
property ShowHint default True;
property TabOrder;
property TabStop default True;
property Visible;
end;
implementation {===============================================================}
uses
CommCtrl{$IFDEF Delphi3}, Menus {$ENDIF};
const
MINCOLSIZE = 32;
DROPDOWNROWS = 8;
{ Return mimimum of two signed integers }
function EMax(A, B: Integer): Integer;
asm
{ ->EAX A
EDX B
<-EAX Min(A, B) }
CMP EAX,EDX
JGE @@Exit
MOV EAX,EDX
@@Exit:
end;
{ Return maximum of two signed integers }
function EMin(A, B: Integer): Integer;
asm
{ ->EAX A
EDX B
<-EAX Max(A, B) }
CMP EAX,EDX
JLE @@Exit
MOV EAX,EDX
@@Exit:
end;
{ TZEditorList }
constructor TZEditorList.Create(APropList: TZPropList);
begin
inherited Create;
FPropList := APropList;
end;
procedure TZEditorList.DeleteEditor(Index: Integer);
var
P: PZEditor;
begin
P := Editors[Index];
{$IFDEF Delphi6}
P.peEditor := nil;
{$ELSE}
P.peEditor.Free;
{$ENDIF}
FreeMem(P);
end;
function TZEditorList.IndexOfPropName(const PropName: string;
StartIndex: Integer): Integer;
var
I: Integer;
begin
if StartIndex < Count then
begin
Result := 0;
for I := StartIndex to Count - 1 do
if Editors[I].peEditor.GetName = PropName then
begin
Result := I;
Exit;
end;
end
else
Result := -1;
end;
function TZEditorList.FindPropName(const PropName: string): Integer;
var
S, Prop: string;
I: Integer;
begin
Result := -1;
S := PropName;
while S <> '' do // Expand subproperties
begin
I := Pos('\', S);
if I > 0 then
begin
Prop := Copy(S, 1, I - 1);
System.Delete(S, 1, I);
end
else
begin
Prop := S;
S := '';
end;
I := IndexOfPropName(Prop, Succ(Result));
if I <= Result then Exit;
Result := I;
if S <> '' then
with Editors[Result]^ do
if peNode then
if not peExpanded then
begin
FPropList.FCurrentIdent := peIdent + 1;
FPropList.FCurrentPos := Result + 1;
try
peEditor.GetProperties(FPropList.PropEnumProc);
except
end;
peExpanded := True;
FPropList.FPropCount := Count;
end
else Exit;
end;
end;
procedure TZEditorList.Add(Editor: PZEditor);
begin
inherited Add(Editor);
end;
procedure TZEditorList.Clear;
var
I: Integer;
begin
for I := 0 to Count - 1 do DeleteEditor(I);
inherited;
end;
function TZEditorList.GetEditor(AIndex: Integer): PZEditor;
begin
Result := Items[AIndex];
end;
{ TZPopupList }
constructor TZPopupList.Create(AOwner: TComponent);
begin
inherited;
Parent := AOwner as TWinControl;
ParentCtl3D := False;
Ctl3D := False;
Visible := False;
TabStop := False;
IntegralHeight := True;
end;
procedure TZPopupList.CreateParams(var Params: TCreateParams);
begin
inherited;
with Params do
begin
Style := Style or WS_BORDER;
ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
X := -200; // move listbox offscreen
{$IFDEF Post4}
AddBiDiModeExStyle(ExStyle);
{$ENDIF}
WindowClass.Style := CS_SAVEBITS;
end;
end;
procedure TZPopupList.CreateWnd;
begin
inherited;
{ if not (csDesigning in ComponentState) then
begin}
Windows.SetParent(Handle, 0);
CallWindowProc(DefWndProc, Handle, WM_SETFOCUS, 0, 0);
// end;
end;
procedure TZPopupList.Hide;
begin
if HandleAllocated and IsWindowVisible(Handle) then
begin
SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
end;
end;
procedure TZPopupList.KeyPress(var Key: Char);
var
TickCount: Integer;
begin
case Key of
#8, #27: FSearchText := '';
#32..#255:
begin
TickCount := GetTickCount;
if TickCount - FSearchTickCount > 2000 then FSearchText := '';
FSearchTickCount := TickCount;
if Length(FSearchText) < 32 then FSearchText := FSearchText + Key;
SendMessage(Handle, LB_SELECTSTRING, WORD(-1), Longint(PChar(FSearchText)));
Key := #0;
end;
end;
inherited Keypress(Key);
end;
{ TZListButton }
constructor TZListButton.Create(AOwner: TComponent);
begin
inherited;
FEditor := AOwner as TZInplaceEdit;
FPropList := FEditor.FPropList;
FButtonWidth := GetSystemMetrics(SM_CXVSCROLL);
FActiveList := TZPopupList.Create(Self);
FActiveList.OnMouseUp := ListMouseUp;
{$IFDEF Delphi5}
FActiveList.OnMeasureItem := MeasureHeight;
FActiveList.OnDrawItem := DrawItem;
{$ENDIF}
end;
procedure TZListButton.Hide;
begin
if HandleAllocated and IsWindowVisible(Handle) then
begin
// Invalidate;
SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_HIDEWINDOW or SWP_NOZORDER or
SWP_NOREDRAW);
end;
end;
procedure TZListButton.Paint;
var
R: TRect;
Flags, X, Y, W: Integer;
begin
R := ClientRect;
InflateRect(R, 1, 1);
Flags := 0;
with Canvas do
if FArrow then
begin
if FPressed then Flags := DFCS_FLAT or DFCS_PUSHED;
DrawFrameControl(Handle, R, DFC_SCROLL, Flags or DFCS_SCROLLCOMBOBOX);
end
else
begin
if FPressed then Flags := BF_FLAT;
DrawEdge(Handle, R, EDGE_RAISED, BF_RECT or BF_MIDDLE or Flags);
X := R.Left + ((R.Right - R.Left) shr 1) - 1 + Ord(FPressed);
Y := R.Top + ((R.Bottom - R.Top) shr 1) - 1 + Ord(FPressed);
W := FButtonWidth shr 3;
if W = 0 then W := 1;
PatBlt(Handle, X, Y, W, W, BLACKNESS);
PatBlt(Handle, X - (W + W), Y, W, W, BLACKNESS);
PatBlt(Handle, X + W + W, Y, W, W, BLACKNESS);
end;
end;
procedure TZListButton.TrackButton(X, Y: Integer);
var
NewState: Boolean;
R: TRect;
begin
R := ClientRect;
NewState := PtInRect(R, Point(X, Y));
if FPressed <> NewState then
begin
FPressed := NewState;
Invalidate;
end;
end;
{$IFDEF Delphi6}
function TZListButton.Editor: IProperty;
{$ELSE}
function TZListButton.Editor: TPropertyEditor;
{$ENDIF}
begin
Result := FPropList.Editor;
end;
type
TGetStrFunc = function(const Value: string): Integer of object;
procedure TZListButton.DropDown;
var
I, M, W: Integer;
P: TPoint;
MCanvas: TCanvas;
AddValue: TGetStrFunc;
begin
if not FListVisible then
begin
FActiveList.Clear;
with Editor do
begin
FActiveList.Sorted := paSortList in GetAttributes;
AddValue := FActiveList.Items.Add;
GetValues(TGetStrProc(AddValue));
SendMessage(FActiveList.Handle, LB_SELECTSTRING, WORD(-1), Longint(PChar(GetValue)));
end;
with FActiveList do
begin
M := EMax(1, EMin(Items.Count, DROPDOWNROWS));
I := ItemHeight;
Height := M * I + 2;
width := Self.Width + FEditor.Width + 1;
end;
with FActiveList do
begin
M := ClientWidth;
MCanvas := FPropList.Canvas;
for I := 0 to Items.Count - 1 do
begin
W := MCanvas.TextWidth(Items[I]) + 4;
if W > M then M := W;
end;
ClientWidth := M;
W := Self.Parent.ClientWidth;
if Width > W then Width := W;
end;
P := Parent.ClientToScreen(Point(Left + Width, Top + Height));
with FActiveList do
begin
if P.Y + Height > Screen.Height then P.Y := P.Y - Self.Height - Height;
SetWindowPos(Handle, HWND_TOP, P.X - Width, P.Y,
0, 0, SWP_NOSIZE + SWP_SHOWWINDOW);
SetActiveWindow(Handle);
end;
SetFocus;
FListVisible := True;
end;
end;
procedure TZListButton.CloseUp(Accept: Boolean);
var
ListValue: string;
Ch: Char;
begin
if FListVisible then
begin
with FActiveList do
begin
if (ItemIndex >= 0) and (ItemIndex < Items.Count) then
ListValue := Items[ItemIndex] else Accept := False;
// Invalidate;
Hide;
Ch := #27; // Emulate ESC
FEditor.KeyPress(Ch);
end;
FListVisible := False;
if Accept then // Emulate ENTER keypress
begin
FEditor.Text := ListValue;
FEditor.Modified := True;
Ch := #13;
FEditor.KeyPress(Ch);
end;
if Focused then FEditor.SetFocus;
end;
end;
procedure TZListButton.StopTracking;
begin
if FTracking then
begin
TrackButton(-1, -1);
FTracking := False;
// MouseCapture := False;
end;
end;
procedure TZListButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
if Button = mbLeft then
begin
if FListVisible then
CloseUp(False)
else
begin
// MouseCapture := True;
FTracking := True;
TrackButton(X, Y);
if FArrow then DropDown;
end;
end;
inherited;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -