main.pas
来自「本系统前端界面采用WINDOWS 窗口风格」· PAS 代码 · 共 662 行 · 第 1/2 页
PAS
662 行
unit Main;
// Virtual Treeview sample application demonstrating clipboard and drag'n drop operations.
// The treeview uses OLE for these operations but can also issue and accept VCL drag'n drop.
// Written by Mike Lischke.
interface
uses
Windows, Messages, ActiveX, SysUtils, Forms, Dialogs, Graphics,
VirtualTrees, ActnList, ComCtrls, ExtCtrls, StdCtrls, Controls, Classes;
type
TMainForm = class(TForm)
ActionList1: TActionList;
CutAction: TAction;
CopyAction: TAction;
PasteAction: TAction;
FontDialog: TFontDialog;
Panel3: TPanel;
Label6: TLabel;
Button1: TButton;
Button3: TButton;
Tree2: TVirtualStringTree;
Label1: TLabel;
Tree1: TVirtualStringTree;
Label2: TLabel;
PageControl1: TPageControl;
LogTabSheet: TTabSheet;
RichTextTabSheet: TTabSheet;
LogListBox: TListBox;
RichEdit1: TRichEdit;
Label3: TLabel;
Label7: TLabel;
Button2: TButton;
TabSheet1: TTabSheet;
Label8: TLabel;
TabSheet2: TTabSheet;
Label4: TLabel;
Label5: TLabel;
Label9: TLabel;
Label10: TLabel;
procedure Button1Click(Sender: TObject);
procedure CutActionExecute(Sender: TObject);
procedure CopyActionExecute(Sender: TObject);
procedure PasteActionExecute(Sender: TObject);
procedure Tree1GetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var Text: WideString);
procedure FormCreate(Sender: TObject);
procedure TreeDragDrop(Sender: TBaseVirtualTree; Source: TObject; DataObject: IDataObject;
Formats: TFormatArray; Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode);
procedure Button2Click(Sender: TObject);
procedure TreeInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode;
var InitialStates: TVirtualNodeInitStates);
procedure Tree1NewText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; Text: WideString);
procedure Button3Click(Sender: TObject);
procedure Tree2DragAllowed(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
procedure TreeDragOver(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState;
Pt: TPoint; Mode: TDropMode; var Effect: Integer; var Accept: Boolean);
procedure Tree2BeforeItemErase(Sender: TBaseVirtualTree; Canvas: TCanvas; Node: PVirtualNode; ItemRect: TRect;
var ItemColor: TColor; var EraseAction: TItemEraseAction);
private
procedure AddUnicodeText(DataObject: IDataObject; Target: TVirtualStringTree; Mode: TVTNodeAttachMode);
procedure AddVCLText(Target: TVirtualStringTree; const Text: WideString; Mode: TVTNodeAttachMode);
function FindCPFormatDescription(CPFormat: Word): string;
procedure InsertData(Sender: TVirtualStringTree; DataObject: IDataObject; Formats: TFormatArray; Effect: Integer;
Mode: TVTNodeAttachMode);
end;
var
MainForm: TMainForm;
//----------------------------------------------------------------------------------------------------------------------
implementation
uses
TypInfo, ShlObj, UrlMon;
{$R *.DFM}
{$R Res\Extra.res} // Contains a little rich text for the rich edit control and a XP manifest.
type
PNodeData = ^TNodeData;
TNodeData = record
Caption: WideString;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.Button1Click(Sender: TObject);
begin
Close;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.CutActionExecute(Sender: TObject);
begin
if ActiveControl = Tree1 then
Tree1.CutToClipboard
else
if ActiveControl = Tree2 then
Tree2.CutToClipboard
else
if ActiveControl = RichEdit1 then
RichEdit1.CutToClipboard;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.CopyActionExecute(Sender: TObject);
begin
if ActiveControl = Tree1 then
Tree1.CopyToClipboard
else
if ActiveControl = Tree2 then
Tree2.CopyToClipboard
else
if ActiveControl = RichEdit1 then
RichEdit1.CopyToClipboard;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.PasteActionExecute(Sender: TObject);
var
DataObject: IDataObject;
EnumFormat: IEnumFormatEtc;
Format: TFormatEtc;
Formats: TFormatArray;
Fetched: Integer;
Tree: TVirtualStringTree;
begin
if ActiveControl is TVirtualStringTree then
begin
Tree := ActiveControl as TVirtualStringTree;
if LogListBox.Items.Count > 0 then
LogListBox.Items.Add('');
if ActiveControl = Tree1 then
LogListBox.Items.Add('----- Tree 1')
else
LogListBox.Items.Add('----- Tree 2');
if Tree.PasteFromClipboard then
LogListBox.Items.Add('Native tree data pasted.')
else
begin
LogListBox.Items.Add('Other data pasted.');
// Some other data was pasted. Enumerate the available formats and try to add the data.
// 1) Get a data object for the data.
OLEGetClipboard(DataObject);
// 2) Enumerate all offered formats and create a format array from it which can be used in InsertData.
if Succeeded(DataObject.EnumFormatEtc(DATADIR_GET, EnumFormat)) then
begin
EnumFormat.Reset;
while EnumFormat.Next(1, Format, @Fetched) = S_OK do
begin
SetLength(Formats, Length(Formats) + 1);
Formats[High(Formats)] := Format.cfFormat;
end;
InsertData(Tree, DataObject, Formats, DROPEFFECT_COPY, Tree.DefaultPasteMode);
end;
end;
end
else
if ActiveControl = RichEdit1 then
RichEdit1.PasteFromClipboard;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.Tree1GetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var Text: WideString);
var
Data: PNodeData;
begin
if TextType = ttNormal then
begin
Data := Sender.GetNodeData(Node);
Text := Data.Caption;
end
else
Text := '';
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.FormCreate(Sender: TObject);
var
Stream: TResourceStream;
begin
Tree1.NodeDataSize := SizeOf(TNodeData);
Tree1.RootNodeCount := 30;
Tree2.NodeDataSize := SizeOf(TNodeData);
Tree2.RootNodeCount := 30;
// There is a small RTF text stored in the resource to have something to display in the rich edit control.
Stream := TResourceStream.Create(HInstance, 'RTF', 'RCDATA');
try
RichEdit1.Lines.LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.AddUnicodeText(DataObject: IDataObject; Target: TVirtualStringTree; Mode: TVTNodeAttachMode);
// This method is called when the drop handler gets called with Unicode text as only
// understandable clipboard format. This text is retrieved and splitted in lines.
// Every line is then added as new node.
var
FormatEtc: TFormatEtc;
Medium: TStgMedium;
OLEData,
Head, Tail: PWideChar;
TargetNode,
Node: PVirtualNode;
Data: PNodeData;
begin
if Mode <> amNowhere then
begin
// fill the structure used to get the Unicode string
with FormatEtc do
begin
cfFormat := CF_UNICODETEXT;
// no specific target device
ptd := nil;
// normal content to render
dwAspect := DVASPECT_CONTENT;
// no specific page of multipage data
lindex := -1;
// pass the data via memory
tymed := TYMED_HGLOBAL;
end;
// Check if we can get the Unicode text data.
if DataObject.QueryGetData(FormatEtc) = S_OK then
begin
// Data is accessible so finally get a pointer to it
if DataObject.GetData(FormatEtc, Medium) = S_OK then
begin
OLEData := GlobalLock(Medium.hGlobal);
if Assigned(OLEData) then
begin
Target.BeginUpdate;
TargetNode := Target.DropTargetNode;
if TargetNode = nil then
TargetNode := Target.FocusedNode;
Head := OLEData;
try
while Head^ <> #0 do
begin
Tail := Head;
while not (Tail^ in [WideChar(#0), WideChar(#13), WideChar(#10)]) do
Inc(Tail);
if Head <> Tail then
begin
// add a new node if we got a non-empty caption
Node := Target.InsertNode(TargetNode, Mode);
Data := Target.GetNodeData(Node);
SetString(Data.Caption, Head, Tail - Head);
end;
// skip line separators
if Tail^ = #13 then
Inc(Tail);
if Tail^ = #10 then
Inc(Tail);
Head := Tail;
end;
finally
GlobalUnlock(Medium.hGlobal);
Target.EndUpdate;
end;
end;
// never forget to free the storage medium
ReleaseStgMedium(Medium);
end;
end;
end;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.AddVCLText(Target: TVirtualStringTree; const Text: WideString; Mode: TVTNodeAttachMode);
// This method is called when the drop handler gets called with a VCL drag source.
// The given text is retrieved and splitted in lines.
var
Head, Tail: PWideChar;
TargetNode,
Node: PVirtualNode;
Data: PNodeData;
begin
if Mode <> amNowhere then
begin
Target.BeginUpdate;
try
TargetNode := Target.DropTargetNode;
if TargetNode = nil then
TargetNode := Target.FocusedNode;
Head := PWideChar(Text);
while Head^ <> #0 do
begin
Tail := Head;
while not (Tail^ in [WideChar(#0), WideChar(#13), WideChar(#10)]) do
Inc(Tail);
if Head <> Tail then
begin
// add a new node if we got a non-empty caption
Node := Target.InsertNode(TargetNode, Mode);
Data := Target.GetNodeData(Node);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?