📄 zproplst.pas
字号:
end;
procedure TZListButton.MouseMove(Shift: TShiftState; X, Y: Integer);
var
ListPos: TPoint;
MousePos: TSmallPoint;
begin
if FTracking then
begin
TrackButton(X, Y);
if FListVisible then
begin
ListPos := FActiveList.ScreenToClient(ClientToScreen(Point(X, Y)));
if PtInRect(FActiveList.ClientRect, ListPos) then
begin
StopTracking;
MousePos := PointToSmallPoint(ListPos);
SendMessage(FActiveList.Handle, WM_LBUTTONDOWN, 0, Integer(MousePos));
Exit;
end;
end;
end;
inherited;
end;
procedure TZListButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var
WasPressed: Boolean;
begin
WasPressed := FPressed;
StopTracking;
if (Button = mbLeft) and not FArrow and WasPressed then FEditor.DblClick;
inherited;
end;
procedure TZListButton.ListMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
CloseUp(PtInRect(FActiveList.ClientRect, Point(X, Y)));
end;
procedure TZListButton.DoDropDownKeys(var Key: Word; Shift: TShiftState);
begin
case Key of
VK_RETURN, VK_ESCAPE:
if FListVisible and not (ssAlt in Shift) then
begin
CloseUp(Key = VK_RETURN);
Key := 0;
end;
else
end;
end;
procedure TZListButton.CMCancelMode(var Message: TCMCancelMode);
begin
inherited;
if (Message.Sender <> Self) and (Message.Sender <> FActiveList) then
CloseUp(False);
end;
procedure TZListButton.WMCancelMode(var Msg: TWMKillFocus);
begin
StopTracking;
inherited;
end;
procedure TZListButton.WMKillFocus(var Msg: TWMKillFocus);
begin
inherited;
CloseUp(False);
end;
procedure TZListButton.KeyPress(var Key: Char);
begin
if FListVisible then FActiveList.KeyPress(Key);
end;
procedure TZListButton.WndProc(var Message: TMessage);
begin
case Message.Msg of
WM_KEYDOWN, WM_SYSKEYDOWN, WM_CHAR:
with TWMKey(Message) do
begin
DoDropDownKeys(CharCode, KeyDataToShiftState(KeyData));
if (CharCode <> 0) and FListVisible then
begin
with TMessage(Message) do
SendMessage(FActiveList.Handle, Msg, WParam, LParam);
Exit;
end;
end
end;
inherited;
end;
procedure TZListButton.WMGetDlgCode(var Msg: TWMGetDlgCode);
begin
Msg.Result := DLGC_WANTARROWS;
end;
{$IFDEF Delphi5}
procedure TZListButton.MeasureHeight(Control: TWinControl; Index: Integer;
var Height: Integer);
begin
Height := FListItemHeight;
end;
procedure TZListButton.DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
begin
Height := FListItemHeight;
end;
procedure TZListButton.CMFontChanged(var Message: TMessage);
begin
inherited;
Canvas.Font := FPropList.Font;
FListItemHeight := Canvas.TextHeight('Wg') + 2;
end;
{$ENDIF}
{ TZInplaceEdit }
constructor TZInplaceEdit.Create(AOwner: TComponent);
begin
inherited;
Parent := AOwner as TWinControl;
FPropList := AOwner as TZPropList;
FListButton := TZListButton.Create(Self);
FListButton.Parent := Parent;
ParentCtl3D := False;
Ctl3D := False;
TabStop := False;
BorderStyle := bsNone;
Visible := False;
end;
procedure TZInplaceEdit.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.Style := Params.Style or ES_MULTILINE;
end;
procedure TZInplaceEdit.InternalMove(const Loc: TRect; Redraw: Boolean);
var
W, H: Integer;
ButtonVisible: Boolean;
begin
if IsRectEmpty(Loc) then Exit;
Redraw := Redraw or not IsWindowVisible(Handle);
with Loc do
begin
W := Right - Left;
H := Bottom - Top;
FPropType := FPropList.GetPropType;
ButtonVisible := (FPropType <> ptSimple);
if ButtonVisible then Dec(W, FListButton.FButtonWidth);
SetWindowPos(Handle, HWND_TOP, Left, Top, W, H,
SWP_SHOWWINDOW or SWP_NOREDRAW);
if ButtonVisible then
begin
FListButton.FArrow := FPropType = ptPickList;
SetWindowPos(FListButton.Handle, HWND_TOP, Left + W, Top,
FListButton.FButtonWidth, H, SWP_SHOWWINDOW or SWP_NOREDRAW);
end
else FListButton.Hide;
end;
BoundsChanged;
if Redraw then
begin
Invalidate;
FListButton.Invalidate;
end;
if FPropList.Focused then Windows.SetFocus(Handle);
end;
procedure TZInplaceEdit.BoundsChanged;
var
R: TRect;
begin
R := Rect(2, 1, Width - 2, Height);
SendMessage(Handle, EM_SETRECTNP, 0, Integer(@R));
SendMessage(Handle, EM_SCROLLCARET, 0, 0);
end;
procedure TZInplaceEdit.UpdateLoc(const Loc: TRect);
begin
InternalMove(Loc, False);
end;
procedure TZInplaceEdit.Move(const Loc: TRect);
begin
InternalMove(Loc, True);
end;
procedure TZInplaceEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
// OutputDebugString('KeyDown');
if (Key = VK_DOWN) and (ssAlt in Shift) then
with FListButton do
begin
if (FPropType = ptPickList) and not FListVisible then DropDown;
Key := 0;
end;
FIgnoreChange := Key = VK_DELETE;
FPropList.KeyDown(Key, Shift);
if Key in [VK_UP, VK_DOWN, VK_PRIOR, VK_NEXT] then Key := 0;
end;
procedure TZInplaceEdit.KeyUp(var Key: Word; Shift: TShiftState);
begin
// OutputDebugString('KeyUp');
FPropList.KeyUp(Key, Shift);
end;
procedure TZInplaceEdit.SetFocus;
begin
if IsWindowVisible(Handle) then
Windows.SetFocus(Handle);
end;
procedure TZInplaceEdit.WMSetFocus(var Msg: TWMSetFocus);
begin
inherited;
DestroyCaret;
CreateCaret(Handle, 0, 1, FPropList.Canvas.TextHeight('A'));
ShowCaret(Handle);
end;
procedure TZInplaceEdit.KeyPress(var Key: Char);
begin
// OutputDebugString('KeyPress');
// FPropList.KeyPress(Key);
FIgnoreChange := (Key = #8) or (SelText <> '');
case Key of
#10: DblClick; // Ctrl + ENTER;
#13: if Modified then FPropList.UpdateText(True) else SelectAll;
#27: with FPropList do
if paRevertable in Editor.getAttributes then UpdateEditor(False);
else Exit;
end;
Key := #0;
end;
procedure TZInplaceEdit.WMKillFocus(var Msg: TWMKillFocus);
begin
inherited;
if (Msg.FocusedWnd <> FPropList.Handle) and
(Msg.FocusedWnd <> FListButton.Handle) then
if not FPropList.UpdateText(True) then SetFocus;
end;
procedure TZInplaceEdit.DblClick;
begin
FPropList.Edit;
end;
procedure TZInplaceEdit.WndProc(var Message: TMessage);
begin
case Message.Msg of
WM_LBUTTONDOWN:
begin
if UINT(GetMessageTime - FClickTime) < GetDoubleClickTime then
Message.Msg := WM_LBUTTONDBLCLK;
FClickTime := 0;
end;
end;
inherited;
end;
procedure TZInplaceEdit.AutoComplete(const S: string);
var
I: Integer;
Values: TStringList;
AddValue: TGetStrFunc;
begin
Values := TStringList.Create;
try
AddValue := Values.Add;
FPropList.Editor.GetValues(TGetStrProc(AddValue));
for I := 0 to Values.Count - 1 do
if StrLIComp(PChar(S), PChar(Values[I]), Length(S)) = 0 then
begin
SendMessage(Handle, WM_SETTEXT, 0, Integer(Values[I]));
SendMessage(Handle, EM_SETSEL, Length(S), Length(Values[I]));
Modified := True;
Break;
end;
finally
Values.Free;
end;
end;
procedure TZInplaceEdit.Change;
begin
inherited;
if Modified then
begin
// OutputDebugString(PChar('Change, Text = "' + Text + '"'));
if (FPropType = ptPickList) and not FIgnoreChange then
AutoComplete(Text);
FIgnoreChange := False;
if FAutoUpdate then FPropList.UpdateText(False);
end;
end;
{ TZPropList }
constructor TZPropList.Create(AOwner: TComponent);
const
PropListStyle = [csCaptureMouse, csOpaque, csDoubleClicks];
begin
inherited;
FInplaceEdit := TZInplaceEdit.Create(Self);
FPropColor := clNavy;
FEditors := TZEditorList.Create(Self);
FDesigner := TZFormDesigner.Create(Self);
{$IFDEF Post4}
FDesigner._AddRef;
{$ENDIF}
{$IFDEF Delphi5}
FNewButtons := True;
{$ENDIF}
FCurrent := -1;
FFilter := tkProperties;
FBorderStyle := bsSingle;
if NewStyleControls then
ControlStyle := PropListStyle else
ControlStyle := PropListStyle + [csFramed];
Color := clBtnFace;
ParentColor := False;
TabStop := True;
SetBounds(Left, Top, 200, 200);
FVertLine := 85;
ShowHint := True;
ParentShowHint := False;
// CurObj := Self;
// DoubleBuffered := False;
end;
procedure TZPropList.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
Style := Style + WS_TABSTOP;
Style := Style + WS_VSCROLL;
WindowClass.style := CS_DBLCLKS;
if FBorderStyle = bsSingle then
if NewStyleControls and Ctl3D then
begin
Style := Style and not WS_BORDER;
ExStyle := ExStyle or WS_EX_CLIENTEDGE;
end
else
Style := Style or WS_BORDER;
end;
end;
procedure TZPropList.InitCurrent(const PropName: string);
begin
// FCurrent := FEditors.FindPropName(PropName);
MoveCurrent(FEditors.FindPropName(PropName));
// if Assigned(FInplaceEdit) then FInplaceEdit.Move(GetEditRect);
end;
procedure TZPropList.FreePropList;
begin
FEditors.Clear;
FPropCount := 0;
end;
procedure TZPropList.InitPropList;
var
Components: {$IFDEF Delphi6}IDesignerSelections{$ELSE}{$IFDEF Delphi5}TDesignerSelectionList{$ELSE}TComponentList{$ENDIF}{$ENDIF};
begin
Components := {$IFDEF Delphi6}CreateSelectionList{$ELSE}{$IFDEF Delphi5}TDesignerSelectionList.Create{$ELSE}TComponentList.Create{$ENDIF}{$ENDIF};
try
Components.Add(TPersistent(FCurObj));
FCurrentIdent := 0;
FCurrentPos := 0;
GetComponentProperties(Components, FFilter, FDesigner, PropEnumProc);
FPropCount := FEditors.Count;
finally
{$IFDEF Delphi6}
Components := nil;
{$ELSE}
Components.Free;
{$ENDIF}
end;
end;
function TZPropList.GetFullPropName(Index: Integer): string;
begin
Result := FEditors[Index].peEditor.GetName;
while Index > 0 do
begin
if FEditors[Pred(Index)].peIdent <> FEditors[Index].peIdent then
Result := FEditors[Pred(Index)].peEditor.GetName + '\' + Result;
Dec(Index);
end;
end;
procedure TZPropList.ChangeCurObj(const Value: TObject);
var
SavedPropName: string;
begin
if (FCurrent >= 0) and (FCurrent < FPropCount) then
SavedPropName := GetFullPropName(FCurrent)
else SavedPropName := '';
FCurObj := Value;
FreePropList;
if not FDestroying then
begin
InitCurrent('');
if Assigned(Value) then
begin
InitPropList;
InitCurrent(SavedPropName);
UpdateEditor(True);
end;
Invalidate;
UpdateScrollRange;
end;
end;
procedure TZPropList.SetCurObj(const Value: TObject);
begin
if FCurObj <> Value then
begin
if Assigned(FOnNewObject) then FOnNewObject(Self, FCurObj, Value);
if not FDestroying then
FInplaceEdit.Modified := False;
FModified := False;
ChangeCurObj(Value);
if Value is TComponent then
TComponent(Value).FreeNotification(Self);
end;
end;
procedure TZPropList.CMFontChanged(var Message: TMessage);
begin
inherited;
Canvas.Font := Font;
FRowHeight := Canvas.TextHeight('Wg') + 3;
Invalidate;
UpdateScrollRange;
FInplaceEdit.Move(GetEditRect);
end;
procedure TZPropList.UpdateScrollRange;
var
si: TScrollInfo;
diVisibleCount, diCurrentPos: Integer;
begin
if not FHasScrollBar or not HandleAllocated or not Showing then Exit;
{ Temporarily mark us as not having scroll bars to avoid recursion }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -