editors.pas

来自「本系统前端界面采用WINDOWS 窗口风格」· PAS 代码 · 共 631 行 · 第 1/2 页

PAS
631
字号
unit Editors;

// Utility unit for the advanced Virtual Treeview demo application which contains the implementation of edit link
// interfaces used in other samples of the demo.

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, VirtualTrees, ExtDlgs, ImgList, Buttons, ExtCtrls, ComCtrls,
  Mask;

type
  // Describes the type of value a property tree node stores in its data property.
  TValueType = (
    vtNone,
    vtString,
    vtPickString,
    vtNumber,
    vtPickNumber,
    vtMemo,
    vtDate
  );

//----------------------------------------------------------------------------------------------------------------------

type
  // Node data record for the the document properties treeview.
  PPropertyData = ^TPropertyData;
  TPropertyData = record
    ValueType: TValueType;
    Value: WideString;      // This value can actually be a date or a number too.
    Changed: Boolean;
  end;

  // Our own edit link to implement several different node editors.
  TPropertyEditLink = class(TInterfacedObject, IVTEditLink)
  private
    FEdit: TWinControl;        // One of the property editor classes.
    FTree: TVirtualStringTree; // A back reference to the tree calling.
    FNode: PVirtualNode;       // The node being edited.
    FColumn: Integer;          // The column of the node being edited.
    FOldEditProc: TWndMethod;  // Used to capture some important messages
                               // regardless of the type of edit control we use.
  protected
    procedure EditWindowProc(var Message: TMessage);
    procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  public
    destructor Destroy; override;

    function BeginEdit: Boolean; stdcall;
    function CancelEdit: Boolean; stdcall;
    function EndEdit: Boolean; stdcall;
    function GetBounds: TRect; stdcall;
    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
    procedure ProcessMessage(var Message: TMessage); stdcall;
    procedure SetBounds(R: TRect); stdcall;
  end;

//----------------------------------------------------------------------------------------------------------------------

type
  TPropertyTextKind = (
    ptkText,
    ptkHint
  );

// The following constants provide the property tree with default data.

const
  // Types of editors to use for a certain node in VST3.
  ValueTypes: array[0..1, 0..12] of TValueType = (
    (
      vtString,     // Title
      vtString,     // Theme
      vtPickString, // Category
      vtMemo,       // Keywords
      vtNone,       // Template
      vtNone,       // Page count
      vtNone,       // Word count
      vtNone,       // Character count
      vtNone,       // Lines
      vtNone,       // Paragraphs
      vtNone,       // Scaled
      vtNone,       // Links to update
      vtMemo),      // Comments
    (
      vtString,     // Author
      vtNone,       // Most recently saved by
      vtNumber,     // Revision number
      vtPickString, // Primary application
      vtString,     // Company name
      vtNone,       // Creation date
      vtDate,       // Most recently saved at
      vtNone,       // Last print
      vtNone,
      vtNone,
      vtNone,
      vtNone,
      vtNone)
  );

  // types of editors to use for a certain node in VST3
  DefaultValue: array[0..1, 0..12] of String = (
    (
      'Virtual Treeview',         // Title
      'native Delphi controls',   // Theme
      'Virtual Controls',         // Category
      'virtual, treeview, VCL',   // Keywords
      'no template used',         // Template
      '> 900',                    // Page count
      '?',                        // Word count
      '~ 1.000.000',              // Character count
      '~ 28.000',                 // Lines
      '',                         // Paragraphs
      'False',                    // Scaled
      'www.delphi-gems.com',    // Links to update
      'Virtual Treeview is much more than a simple treeview.'), // Comments
    (
      'Dipl. Ing. Mike Lischke',  // Author
      'Mike Lischke',             // Most recently saved by
      '3.0',                      // Revision number
      'Delphi',                   // Primary application
      '',                         // Company name
      'July 1999',                // Creation date
      'January 2002',             // Most recently saved at
      '',                         // Last print
      '',
      '',
      '',
      '',
      '')
  );

  // Fixed strings for property tree (VST3).
  PropertyTexts: array[0..1, 0..12, TPropertyTextKind] of string = (
    (// first (upper) subtree
     ('Title', 'Title of the file or document'),
     ('Theme', 'Theme of the file or document'),
     ('Category', 'Category of theme'),
     ('Keywords', 'List of keywords which describe the content of the file'),
     ('Template', 'Name of the template which was used to create the document'),
     ('Page count', 'Number of pages in the document'),
     ('Word count', 'Number of words in the document'),
     ('Character count', 'Number of characters in the document'),
     ('Lines', 'Number of lines in the document'),
     ('Paragraphs', 'Number of paragraphs in the document'),
     ('Scaled', 'Scaling of the document for output'),
     ('Links to update', 'Links which must be updated'),
     ('Comments', 'Description or comments for the file')
     ),
    (// second (lower) subtree
     ('Author', 'name of the author of the file or document'),
     ('Most recently saved by', 'Name of the person who has saved the document last'),
     ('Revision number', 'Revision number of the file or document'),
     ('Primary application', 'Name of the application which is primarily used to create this kind of file'),
     ('Company name', 'Name of the company or institution'),
     ('Creation date', 'Date when the file or document was created'),
     ('Most recently saved at', 'Date when the file or document was saved the last time'),
     ('Last print', 'Date when the file or document was printed the last time'),
     ('', ''),   // the remaining 5 entries are not used
     ('', ''),
     ('', ''),
     ('', ''),
     ('', '')
   )
  );

//----------------------------------------------------------------------------------------------------------------------

type
  PGridData = ^TGridData;
  TGridData = record
    ValueType: array[0..3] of TValueType; // one for each column
    Value: array[0..3] of Variant;
    Changed: Boolean;
  end;

  // Our own edit link to implement several different node editors.
  TGridEditLink = class(TPropertyEditLink, IVTEditLink)
  public
    function EndEdit: Boolean; stdcall;
    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
  end;

//----------------------------------------------------------------------------------------------------------------------

implementation

uses
  PropertiesDemo, GridDemo;

//----------------- TPropertyEditLink ----------------------------------------------------------------------------------

// This implementation is used in VST3 to make a connection beween the tree
// and the actual edit window which might be a simple edit, a combobox
// or a memo etc.

destructor TPropertyEditLink.Destroy;

begin
  FEdit.Free;
  inherited;
end;

//----------------------------------------------------------------------------------------------------------------------

procedure TPropertyEditLink.EditWindowProc(var Message: TMessage);

// Here we can capture messages for keeping track of focus changes.

begin
  case Message.Msg of
    WM_KILLFOCUS:
      if FEdit is TDateTimePicker then
      begin
        // When the user clicks on a dropped down calender we also get
        // the kill focus message.
        if not TDateTimePicker(FEdit).DroppedDown then
          FTree.EndEditNode;
      end
      else
        FTree.EndEditNode;
  else
    FOldEditProc(Message);
  end;
end;

//----------------------------------------------------------------------------------------------------------------------

procedure TPropertyEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

var
  CanAdvance: Boolean;
  
begin
  case Key of
    VK_RETURN,
    VK_UP,
    VK_DOWN:
      begin
        // Consider special cases before finishing edit mode.
        CanAdvance := Shift = [];
        if FEdit is TComboBox then
          CanAdvance := CanAdvance and not TComboBox(FEdit).DroppedDown;
        if FEdit is TDateTimePicker then
          CanAdvance :=  CanAdvance and not TDateTimePicker(FEdit).DroppedDown;

        if CanAdvance then
        begin
          FTree.EndEditNode;
          with FTree do
          begin
            if Key = VK_UP then
              FocusedNode := GetPreviousVisible(FocusedNode)
            else
              FocusedNode := GetNextVisible(FocusedNode);
            Selected[FocusedNode] := True;
          end;
          Key := 0;
        end;
      end;
  end;
end;

//----------------------------------------------------------------------------------------------------------------------

function TPropertyEditLink.BeginEdit: Boolean;

begin
  Result := True;
  FEdit.Show;
  FEdit.SetFocus;
  // Set a window procedure hook (aka subclassing) to get notified about important messages.
  FOldEditProc := FEdit.WindowProc;
  FEdit.WindowProc := EditWindowProc;
end;

//----------------------------------------------------------------------------------------------------------------------

function TPropertyEditLink.CancelEdit: Boolean;

begin
  Result := True;
  // Restore the edit's window proc.
  FEdit.WindowProc := FOldEditProc;
  FEdit.Hide;
end;

//----------------------------------------------------------------------------------------------------------------------

function TPropertyEditLink.EndEdit: Boolean;

var
  Data: PPropertyData;
  Buffer: array[0..1024] of Char;
  S: WideString;
  P: TPoint;
  Dummy: Integer;

begin
  // Check if the place the user click on yields another node as the one we
  // are currently editing. If not then do not stop editing.
  GetCursorPos(P);
  P := FTree.ScreenToClient(P);
  Result := FTree.GetNodeAt(P.X, P.Y, True, Dummy) <> FNode;

  if Result then
  begin
    // restore the edit's window proc
    FEdit.WindowProc := FOldEditProc;
    Data := FTree.GetNodeData(FNode);
    if FEdit is TComboBox then
      S := TComboBox(FEdit).Text
    else
    begin

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?