📄 rm_insp.pas
字号:
{******************************************}
{ }
{ Report Machine v2.0 }
{ Object Inspector }
{ }
{******************************************}
unit RM_insp;
interface
{$I RM.inc}
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, Buttons, RM_Class, RM_Pars
{$IFDEF Delphi6}, Variants{$ENDIF};
type
TModifyEvent = procedure(Item: Integer) of object;
TGetObjectsEvent = procedure(List: TStrings) of object;
TSelectionChangedEvent = procedure(ObjName: string) of object;
TRMInspForm = class;
{ TProp }
TProp = class(TObject)
private
procedure SetValue(Value: Variant);
function GetValue: Variant;
function IsEnumNull: Boolean;
public
Text: string;
DataType: TRMDataTypes;
Editor: TNotifyEvent;
Enum: TStringList;
EnumValues: Variant;
constructor Create(PropValue: Variant; PropType: TRMDataTypes;
PropEnum: TStringList; PropEnumValues: Variant; PropEditor: TNotifyEvent); virtual;
destructor Destroy; override;
property Value: Variant read GetValue write SetValue;
end;
{ TRMPopupListBox }
TRMPopupListbox = class(TCustomListbox)
private
FInspForm: TRMInspForm;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
end;
{ TRMInspForm }
TRMInspForm = class(TForm)
CB1: TComboBox;
Box: TScrollBox;
PaintBox1: TPaintBox;
Edit1: TEdit;
EditPanel: TPanel;
ComboPanel: TPanel;
ComboBtn: TSpeedButton;
EditBtn: TSpeedButton;
procedure PaintBox1Paint(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure EditBtnClick(Sender: TObject);
procedure FormDeactivate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Edit1DblClick(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure FormResize(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure CB1DropDown(Sender: TObject);
procedure CB1Click(Sender: TObject);
procedure CB1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
procedure ComboBtnClick(Sender: TObject);
procedure LB1Click(Sender: TObject);
procedure Edit1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
FListVisible: Boolean;
FItems: TStringList;
FItemIndex: Integer;
FOnModify: TModifyEvent;
FRowHeight: Integer;
Fw, Fw1: Integer;
Fb: TBitmap;
FBusyFlag, FBusyFlag1: Boolean;
FDefHeight: Integer;
FLB1: TRMPopupListBox;
FTickCount: Integer;
FPanel1: TPanel;
FDown: Boolean;
FLastProp: string;
FPropAliases: TRMVariables;
FOnHeightChanged: TNotifyEvent;
FOnGetObjects: TGetObjectsEvent;
FOnSelectionChanged: TSelectionChangedEvent;
procedure SetItems(Value: TStringList);
procedure SetItemIndex(Value: Integer);
function GetCount: Integer;
procedure DrawOneLine(index: Integer; a: Boolean);
procedure SetItemValue(Value: string);
function GetItemValue(i: Integer): string;
function CurItem: TProp;
procedure WMNCLButtonDblClk(var Message: TMessage); message WM_NCLBUTTONDBLCLK;
function GetPropValue(Index: Integer): Variant;
procedure SetPropValue(Index: Integer; Value: Variant);
function GetClassName(ObjName: string): string;
procedure FillPropAliases;
//WHF Add
function GetItemType(i: Integer): TRMDataTypes;
procedure OnEventDrawItemColor(Control: TWinControl; AIndex: Integer;
ARect: TRect; State: TOwnerDrawState);
function GetPropName(Index: Integer): string;
procedure Localize;
public
{ Public declarations }
CurObject: TObject;
ObjectName: string;
HideProperties: Boolean;
procedure CreateParams(var Params: TCreateParams); override;
procedure ClearProperties;
procedure AddProperty(PropName: string; PropValue: Variant; PropType: TRMDataTypes;
PropEnum: TStringList; PropEnumValues: Variant; PropEditor: TNotifyEvent);
procedure CloseUp(Accept: Boolean);
procedure ItemsChanged;
procedure Grow;
property PropValue[Index: Integer]: Variant read GetPropValue write SetPropValue;
property Items: TStringList read FItems write SetItems;
property ItemIndex: Integer read FItemIndex write SetItemIndex;
property Count: Integer read GetCount;
property SplitterPos: Integer read Fw1 write Fw1;
property OnModify: TModifyEvent read FOnModify write FOnModify;
property OnHeightChanged: TNotifyEvent read FOnHeightChanged write FOnHeightChanged;
property OnGetObjects: TGetObjectsEvent read FOnGetObjects write FOnGetObjects;
property OnSelectionChanged: TSelectionChangedEvent read FOnSelectionChanged write FOnSelectionChanged;
end;
implementation
uses RM_Desgn, RM_Utils, RM_Const, RM_Const1;
{$R *.DFM}
{$R RM_LNG5.RES}
type
TInspPanel = class(TPanel)
protected
procedure WMEraseBackground(var Message: TMessage); message WM_ERASEBKGND;
procedure Paint; override;
end;
{============================================================================}
{============================================================================}
{ TInspPanel }
procedure TInspPanel.WMEraseBackground(var Message: TMessage);
begin
end;
procedure TInspPanel.Paint;
begin
end;
{============================================================================}
{============================================================================}
{ TRMPopupListBox }
procedure TRMPopupListBox.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or WS_BORDER;
ExStyle := WS_EX_TOOLWINDOW;
WindowClass.Style := CS_SAVEBITS;
end;
end;
procedure TRMPopupListbox.CreateWnd;
begin
inherited CreateWnd;
Windows.SetParent(Handle, 0);
CallWindowProc(DefWndProc, Handle, wm_SetFocus, 0, 0);
end;
{============================================================================}
{============================================================================}
{ TProp }
constructor TProp.Create(PropValue: Variant; PropType: TRMDataTypes;
PropEnum: TStringList; PropEnumValues: Variant; PropEditor: TNotifyEvent);
begin
inherited Create;
DataType := PropType;
Editor := PropEditor;
Enum := PropEnum;
EnumValues := PropEnumValues;
Value := PropValue;
end;
destructor TProp.Destroy;
begin
EnumValues := 0;
inherited Destroy;
end;
function TProp.IsEnumNull: Boolean;
begin
Result := TVarData(EnumValues).VType < varArray;
end;
procedure TProp.SetValue(Value: Variant);
function ConvertToFloat(s: string): string;
var
v: Double;
begin
v := StrToFloat(s);
Result := FloatToStrF(v, ffFixed, 4, 2);
end;
function ConvertToColor(s: string): string;
var
i, v: Integer;
begin
v := StrToInt(s);
Result := '$' + IntToHex(v, 6);
for i := 0 to 41 do
begin
if v = RMColors[i] then
begin
Result := RMColorNames[i];
Break;
end;
end;
end;
function ConvertToBoolean(s: string): string;
var
v: Integer;
begin
if AnsiCompareText(s, 'True') = 0 then
v := 1
else if AnsiCompareText(s, 'False') = 0 then
v := 0
else
v := StrToInt(s);
if v <> 0 then
Result := 'True'
else
Result := 'False';
end;
function ConvertFromEnum(s: string): string;
var
i: Integer;
begin
Result := s;
for i := 0 to VarArrayHighBound(EnumValues, 1) do
begin
if EnumValues[i] = StrToInt(s) then
Result := Enum[i];
end;
end;
begin
Text := Value;
if Text <> '' then
begin
if RMdtFloat in DataType then
Text := ConvertToFloat(Text)
else if RMdtBoolean in DataType then
Text := ConvertToBoolean(Text)
else if RMdtColor in DataType then
Text := ConvertToColor(Text)
else if (RMdtEnum in DataType) and (not IsEnumNull) then
Text := ConvertFromEnum(Text);
end;
end;
function TProp.GetValue: Variant;
var
n: integer;
function ConvertFromColor(s: string): Integer;
var
i: Integer;
begin
for i := 0 to 41 do
begin
if AnsiCompareText(s, RMColorNames[i]) = 0 then
begin
Result := RMColors[i];
Exit;
end;
end;
if Length(s) > 0 then
Result := StrToInt(s)
else
Result := 16;
end;
function ConvertFromBoolean(s: string): Boolean;
begin
s := AnsiUpperCase(s);
Result := False;
if s = 'TRUE' then
Result := True
else if s = 'FALSE' then
Result := False
else if (s <> '') and (s <> '0') then
Result := True;
end;
function ConvertFromDate(s: string): TDateTime;
var
SaveFormat: string;
SaveDateSeparator: char;
begin
SaveFormat := SysUtils.ShortDateFormat;
SaveDateSeparator := SysUtils.DateSeparator;
SysUtils.ShortDateFormat := 'yyyy/mm/dd';
SysUtils.DateSeparator := '/';
Result := StrToDate(Text);
SysUtils.ShortDateFormat := SaveFormat;
SysUtils.DateSeparator := SaveDateSeparator;
end;
begin
Result := Null;
if (RMdtString in DataType) or ((RMdtEnum in DataType) and IsEnumNull) then
Result := Text
else if RMdtInteger in DataType then
Result := StrToInt(Text)
else if RMdtFloat in DataType then
Result := RMStrToFloat(Text)
else if RMdtBoolean in DataType then
Result := ConvertFromBoolean(Text)
else if RMdtColor in DataType then
Result := ConvertFromColor(Text)
else if rmdtDate in DataType then
Result := ConvertFromDate(Text)
else if RMdtEnum in DataType then
begin
n := Enum.IndexOf(Text);
if n <> -1 then
Result := EnumValues[n]
else
Result := StrToInt(Text);
end;
end;
{============================================================================}
{============================================================================}
{ TRMInspForm }
//WHF Add
procedure TRMInspForm.Localize;
begin
Font.Name := RMLoadStr(SRMDefaultFontName);
Font.Size := StrToInt(RMLoadStr(SRMDefaultFontSize));
Font.Charset := StrToInt(RMLoadStr(SCharset));
Caption := RMLoadStr(rmRes + 059);
end;
procedure TRMInspForm.CloseUp(Accept: Boolean);
var
ListValue: Variant;
begin
if FListVisible then
begin
if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
if FLB1.ItemIndex <> -1 then
ListValue := FLB1.Items[FLB1.ItemIndex];
SetWindowPos(FLB1.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
FListVisible := False;
end;
end;
function TRMInspForm.GetItemType(i: Integer): TRMDataTypes;
var
p: TProp;
begin
Result := [];
p := TProp(FItems.Objects[i]);
if p = nil then Exit;
Result := p.DataType;
end;
procedure TRMInspForm.OnEventDrawItemColor(Control: TWinControl; AIndex: Integer;
ARect: TRect; State: TOwnerDrawState);
var
bmp: TBitmap;
begin
bmp := TBitmap.Create;
bmp.Height := 16; bmp.Width := 16;
bmp.Canvas.Brush.Color := RMColors[AIndex];
bmp.Canvas.Pen.Color := clBlack;
bmp.Canvas.Rectangle(0, 0, 15, 15);
with TCustomListbox(Control) do
begin
Canvas.FillRect(ARect);
Canvas.Draw(ARect.Left, ARect.Top, bmp);
Canvas.TextOut(ARect.Left + 20, ARect.Top + 1, Items[AIndex]);
end;
bmp.Free;
end;
procedure TRMInspForm.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := RMDesigner.Handle;
end;
function TRMInspForm.GetPropValue(Index: Integer): Variant;
begin
Result := TProp(FItems.Objects[Index]).Value;
end;
procedure TRMInspForm.SetPropValue(Index: Integer; Value: Variant);
begin
TProp(FItems.Objects[Index]).Value := Value;
end;
procedure TRMInspForm.ClearProperties;
var
i: Integer;
begin
for i := 0 to FItems.Count - 1 do
TProp(FItems.Objects[i]).Free;
FItems.Clear;
end;
procedure TRMInspForm.AddProperty(PropName: string; PropValue: Variant;
PropType: TRMDataTypes; PropEnum: TStringList; PropEnumValues: Variant;
PropEditor: TNotifyEvent);
begin
FItems.AddObject(PropName, TProp.Create(PropValue, PropType, PropEnum,
PropEnumValues, PropEditor));
end;
function TRMInspForm.CurItem: TProp;
begin
Result := nil;
if (FItemIndex <> -1) and (Count > 0) then
Result := TProp(FItems.Objects[FItemIndex]);
end;
procedure TRMInspForm.SetItems(Value: TStringList);
begin
FItems.Assign(Value);
FItemIndex := -1;
PaintBox1.Repaint;
ItemIndex := 0;
end;
procedure TRMInspForm.SetItemValue(Value: string);
var
p: TProp;
n: Integer;
begin
if HideProperties then Exit;
p := TProp(FItems.Objects[FItemIndex]);
p.Text := Value;
n := FItemIndex;
try
FBusyFlag1 := TRUE;
if Assigned(FOnModify) then FOnModify(FItemIndex);
if n >= FItems.Count then
n := 0;
finally
FBusyFlag1 := FALSE;
SetItemIndex(n);
end;
end;
function TRMInspForm.GetItemValue(i: Integer): string;
var
p: TProp;
SaveFormat: string;
SaveDateSeparator: char;
begin
Result := '';
p := TProp(FItems.Objects[i]);
if p = nil then Exit;
if rmdtDate in p.DataType then
begin
SaveFormat := SysUtils.ShortDateFormat;
SaveDateSeparator := SysUtils.DateSeparator;
SysUtils.ShortDateFormat := 'yyyy/mm/dd';
SysUtils.DateSeparator := '/';
Result := DateToStr(StrToFloat(p.Text));
SysUtils.ShortDateFormat := SaveFormat;
SysUtils.DateSeparator := SaveDateSeparator;
end
else
Result := p.Text;
end;
procedure TRMInspForm.SetItemIndex(Value: Integer);
var
ww, y: Integer;
b1, b2: Boolean;
begin
if FBusyFlag1 then Exit;
if Value > Count - 1 then
Value := Count - 1;
Edit1.Visible := (Count > 0) and not HideProperties;
if Count = 0 then Exit;
if FItemIndex <> -1 then
begin
if Edit1.Modified then
SetItemValue(Edit1.Text);
end;
FItemIndex := Value;
EditPanel.Visible := (CurItem <> nil) and Assigned(CurItem.Editor) and not HideProperties;
ComboPanel.Visible := (CurItem <> nil) and
([RMdtBoolean, RMdtColor, RMdtEnum] * CurItem.DataType <> []) and
not HideProperties;
FLB1.Visible := False;
b1 := (CurItem <> nil) and (RMdtHasEditor in CurItem.DataType);
b2 := (CurItem <> nil) and (RMdtString in CurItem.DataType);
if CurItem = nil then Exit;
Edit1.ReadOnly := b1 and not b2;
ww := Fw - Fw1 - 2;
y := FItemIndex * FRowHeight + 1;
if EditPanel.Visible then
begin
EditPanel.SetBounds(Fw - 14, y, 14, FRowHeight - 2);
Dec(ww, 15);
end;
Edit1.Text := GetItemValue(FItemIndex);
if ComboPanel.Visible then
begin
ComboPanel.SetBounds(Fw - 14, y, 14, FRowHeight - 2);
Dec(ww, 15);
end;
Edit1.SetBounds(Fw1 + 2, y, ww, FRowHeight - 2);
Edit1.SelectAll;
Edit1.Modified := False;
if y + FRowHeight > Box.VertScrollBar.Position + Box.ClientHeight then
Box.VertScrollBar.Position := y - Box.ClientHeight + FRowHeight;
if y < Box.VertScrollBar.Position then
Box.VertScrollBar.Position := y - 1;
FLastProp := FItems[FItemIndex];
PaintBox1Paint(nil);
end;
function TRMInspForm.GetCount: Integer;
begin
Result := FItems.Count;
end;
procedure TRMInspForm.ItemsChanged;
var
LastIndex: Integer;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -