📄 zproplst.~pas
字号:
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;
with Editor do
ListMeasureHeight(GetName, FActiveList.Canvas, Height);
end;
procedure TZListButton.DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
begin
with FActiveList do
Editor.ListDrawValue(Items[Index], Canvas,
Rect, odSelected in State);
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 Delphi5}TDesignerSelectionList{$ELSE}TComponentList{$ENDIF};
begin
Components := {$IFDEF Delphi5}TDesignerSelectionList{$ELSE}TComponentList{$ENDIF}.Create;
try
Components.Add({$IFDEF Delphi2}TComponent{$ELSE}TPersistent{$ENDIF}(FCurObj));
FCurrentIdent := 0;
FCurrentPos := 0;
GetComponentProperties(Components, FFilter, FDesigner, PropEnumProc);
FPropCount := FEditors.Count;
finally
Components.Free;
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 }
FHasScrollBar := False;
try
with si do
begin
cbSize := SizeOf(TScrollInfo);
fMask := SIF_RANGE + SIF_PAGE + SIF_POS;
nMin := 0;
diVisibleCount := VisibleRowCount;
diCurrentPos := FTopRow;
if FPropCount <= diVisibleCount then
begin
nPage := 0;
nMax := 0;
end
else
begin
nPage := diVisibleCount;
nMax := FPropCount - 1;
end;
if diCurrentPos + diVisibleCount > FPropCount then
diCurrentPos := EMax(0, FPropCount - diVisibleCount);
nPos := diCurrentPos;
{$IFDEF Prior4}
SetScrollInfo(Handle, SB_VERT, si, True);
{$ELSE}
FlatSB_SetScrollInfo(Handle, SB_VERT, si, True);
{$ENDIF}
MoveTop(diCurrentPos);
end;
finally
FHasScrollBar := True;
end;
end;
function TZPropList.VisibleRowCount: Integer;
begin
if FRowHeight > 0 then // avoid division by zero
Result := EMin(ClientHeight div FRowHeight, FPropCount)
else
Result := FPropCount;
end;
procedure TZPropList.CMShowingChanged(var Message: TMessage);
begin
inherited;
if Showing then
begin
FHasScrollBar := True;
Perform(CM_FONTCHANGED, 0, 0);
FInplaceEdit.FListButton.Perform(CM_FONTCHANGED, 0, 0);
if csDesigning in ComponentState then CurObj := Self;
Parent.Realign;
{ UpdateScrollRange;
InitCurrent;
UpdateEditor(True);}
end;
end;
procedure TZPropList.WMEraseBkGnd(var Msg: TWMEraseBkGnd);
begin
Msg.Result := 1;
end;
procedure TZPropList.WMSize(var Msg: TWMSize);
begin
inherited;
if FRowHeight <= 0 then Exit;
ColumnSized(FVertLine); // move divider if needed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -