Delphi XE7试用记录2

万一博客中介绍了不少Delphi7以后的新功能测试,想跟着测试一下。每次测试建立一个工程,在窗体上放几个按钮,测试几个相关的功能,这样虽然简单明了,但日后查阅起来不方便。最好能操作简单,尽可能集中到一个项目中,功能分类清晰,同时可以看到运行效果及源代码。

窗体上放置ActionList、MainMen、TreeView、PageControl、Memo。测试代码放到Action中,运行时根据Action自动建立MainMenu和TreeView中的项目,点击MenuItem或TreeNode都可以运行测试代码。Memo中放工程源代码,点击TreeNode不仅可以运行测试代码还可以自动导航到对应的源代码。PageControl中放置测试代码用到的组件,展开TreeNode可以自动显示对应的组件页面。

根据Action建立MainMenu的代码:

procedure Action2Menu(ActionList: TActionList; MainMenu: TMainMenu);

const

MenuEx = 'n8m9uu'; // uu,加在menu item名字中,防止重名

var

Action1: TContainedAction;

MenuItem1: TMenuItem; // uu,一级菜单项

MenuItem2: TMenuItem; // uu,二级菜单项

i, j: integer;

StrCaption: string;

begin

for i := 0 to ActionList.ActionCount - 1 do

begin

Action1 := ActionList.Actions[i];

StrCaption := Action1.Category;

for j := 0 to MainMenu.Items.Count - 1 do

begin // uu,找到名字与动作标题相同的一级菜单项

MenuItem1 := MainMenu.Items.Items[j];

if MenuItem1.Name = MenuEx + StrCaption then

Break;

end;

if (MainMenu.Items.Count = 0) then

begin

// uu,先创建一个一级菜单项,设置名称和标题。

// uu,标题可以会自动添加快捷键或重复,所以要设置名称以便以后查找

MenuItem1 := TMenuItem.Create(MainMenu);

MenuItem1.Name := MenuEx + StrCaption;

MenuItem1.Caption := StrCaption;

MainMenu.Items.Add(MenuItem1);

// uu,再增加子菜单项,设置Action

MenuItem2 := TMenuItem.Create(MainMenu);

MenuItem2.Action := Action1;

MenuItem1.Add(MenuItem2);

end

else

begin

if (MenuItem1.Name = MenuEx + StrCaption) then

begin

// uu,找到同类的菜单项,就在其下添加子菜单项

MenuItem2 := TMenuItem.Create(MainMenu);

MenuItem2.Action := Action1;

MenuItem1.Add(MenuItem2);

end

else

begin

// uu,没有找到同类的菜单项,就新建一个

MenuItem1 := TMenuItem.Create(MainMenu);

MenuItem1.Name := MenuEx + StrCaption;

MenuItem1.Caption := StrCaption;

MainMenu.Items.Add(MenuItem1);

MenuItem2 := TMenuItem.Create(MainMenu);

MenuItem2.Action := Action1;

MenuItem1.Add(MenuItem2);

end;

end;

end;

end;

根据Action建立TreeView的代码:

procedure Action2Tree(ActionList: TActionList; Tree: TTreeView);

var

Action1: TContainedAction;

Node1: TTreeNode;

Node2: TTreeNode;

i: integer;

StrCaption: string;

begin

Tree.Items.Clear;

Tree.ReadOnly := True;

Tree.RowSelect := True;

Tree.HideSelection := True;

for i := 0 to ActionList.ActionCount - 1 do

begin

Action1 := ActionList.Actions[i];

StrCaption := Action1.Category;

Node1 := Tree.TopItem;

// uu,遍历一级节点,查找与分类相同名称的节点

while Assigned(Node1) do

begin

if Node1.Text = StrCaption then

Break;

Node1 := Node1.getNextSibling;

end;

if not Assigned(Node1) then

begin

// uu,Tree中一个节点都没有,先新建一个一级节点

Node1 := Tree.Items.AddChild(nil, StrCaption);

// uu,再新建一个子节点,关联Action

Node2 := Tree.Items.AddChild(Node1, Action1.Caption);

Node2.Data := Action1;

end

else

begin

if Node1.Text = StrCaption then

begin

// uu,找到与分类同名的节点,就在其下新建节点,关联Action

Node2 := Tree.Items.AddChild(Node1, Action1.Caption);

Node2.Data := Action1;

end

else

begin

// uu,没有找到,就新建一级节点,然后再建子节点

Node1 := Tree.Items.AddChild(nil, StrCaption);

Node2 := Tree.Items.AddChild(Node1, Action1.Caption);

Node2.Data := Action1;

end;

end;

end;

end;

点击TreeNode事件的代码:

procedure TFormMain.TreeView1Click(Sender: TObject);

var

Action1: TContainedAction;

strEvent, strCaption: string;

intP: LongInt;

begin

with TreeView1 do

if Assigned(Selected) then

begin

if Assigned(Selected.Data) then

begin

Action1 := TContainedAction(Selected.Data);

// uu,执行

Action1.Execute;

// uu,导航源代码

strEvent := Action1.Name;

strCaption := Action1.Caption;

strEvent := Format('procedure TFormMain.%sExecute(Sender: TObject);', [strEvent]);

intP := Pos(strEvent, MemoSource.Text);

if intP > 0 then

begin

MemoSource.SelStart := intP;

MemoSource.SelLength := Length(strEvent);

MemoSource.SetFocus;

// uu,当前行滚动到第一行

end

else

ShowInfo(Format('%s,没找到源代码', [strCaption]));

end;

end;

end;

展开TreeNode事件的代码:

procedure TFormMain.TreeView1Expanding(Sender: TObject; Node: TTreeNode;

var AllowExpansion: Boolean);

var

i: Integer;

str1,str2: string;

begin

// uu,如果下面的Action无效,则无法展开

// TreeView1.Selected := nil;

// uu,每次只能展开一个分支,所以先合拢所有分支。

TreeView1.FullCollapse;

str1 := Node.Text;

// uu,如果有对应的Tab则显示。多个分支可以共用一个page

for i := 0 to PageControl1.PageCount - 1 do

begin

str2 := PageControl1.Pages[i].Caption;

if str1.Contains(str2) or str2.Contains(str1) then

PageControl1.Pages[i].Show;

end;

end;

窗体的创建事件的代码:

procedure TFormMain.FormCreate(Sender: TObject);

begin

AppPath := ExtractFilePath(Application.ExeName);

// uu,下面两个函数在uuActionFun单元中,用于把Action放到菜单和Tree中。

Action2Menu(ActionList1, MainMenu1);

Action2Tree(ActionList1, TreeView1);

// uu,在测试功能同时显示源代码

if FileExists(CodeFile) then

MemoSource.Lines.LoadFromFile(CodeFile);

end;

以后做简单的测试就可以放到这个工程中了。为了测试D7到XE7的新功能,建立了两个这样的工程,因为一个工程测试代码太多严重影响编辑效率。工程源代码放在网盘上(https://pan.baidu.com/s/1bo7Hskf),有兴趣的可以下载。

Delphi XE7试用记录2的更多相关文章

  1. Delphi XE7试用记录1

    Delphi XE7试用记录1 在网上看到XE7的一些新特征,觉得完整Unicode支持.扩展Pascal语法.更多功能的库都很吸引人,决定试试XE7. XE7官方安装程序很大,因此选择了lite版, ...

  2. RemObjects SDK Source For Delphi XE7

    原文:http://blog.csdn.net/tht2009/article/details/39545545 1.目前官网最新版本是RemObjects SDK for Delphi and al ...

  3. 咏南CS多层插件式开发框架支持最新的DELPHI XE7

    DATASNAP中间件: 中间件已经在好几个实际项目中应用,长时间运行异常稳定,可无人值守: 可编译环境:DELPHI XE5~DELPHI XE7,无需变动代码: 支持传统TCP/IP方式也支持RE ...

  4. Delphi XE7调用C++动态库出现乱码问题回顾

    事情源于有个客户需使用我们C++的中间件动态库来跟设备连接通讯,但是传入以及传出的字符串指针格式都不正确(出现乱码或是被截断),估计是字符编码的问题导致.以下是解决问题的过程: 我们C++中间件动态库 ...

  5. delphi XE7 中的消息

    在delphi XE7的程序开发中,消息机制保证进程间的通信. 在程序中,消息来自: 1)系统: 通知你的程序用户输入,涂画以及其他的系统范围的事件: 2)你的程序:不同的程序部分之间的通信信息.   ...

  6. 关于delphi XE7中的动态数组和并行编程(第一部分)

    本文引自:http://www.danieleteti.it/category/embarcadero/delphi-xe7-embarcadero/ 并行编程库是delphi XE7中引进的最受期待 ...

  7. Delphi XE7中新并行库

    Delphi XE7中添加了新的并行库,和.NET的Task和Parellel相似度99%. 详细内容能够看以下的文章: http://www.delphifeeds.com/go/s/119574 ...

  8. Delphi XE7下如何创建一个Android模拟器调试

    利用Delphi XE7我们可以进行多种设备程序的开发,尤其是移动开发应用程序得到不断地加强.在实际的Android移动程序开发中,如果我们直接用android真机直接调试是非常不错.一是速度快,二是 ...

  9. DELPHI XE7 新的并行库

    DELPHI XE7 的新功能列表里面增加了并行库System.Threading, System.SyncObjs. 为什么要增加新的并行库? 还是为了跨平台.以前要并行编程只能从TThread类继 ...

随机推荐

  1. [转]一千行 MySQL 学习笔记

    原文地址:https://www.cnblogs.com/shockerli/p/1000-plus-line-mysql-notes.html /* 启动MySQL */ net start mys ...

  2. Leetcode1000 合并石头的最低成本 区间DP

    有 N 堆石头排成一排,第 i 堆中有 stones[i] 块石头. 每次移动(move)需要将连续的 K 堆石头合并为一堆,而这个移动的成本为这 K 堆石头的总数. 找出把所有石头合并成一堆的最低成 ...

  3. 转*SqlSever查询某个表的列名称、说明、备注、注释,类型等

    @原文地址 关键部分如下: ------sqlserver 查询某个表的列名称.说明.备注.类型等 SELECT 表名 then d.name else '' end, 表说明 then isnull ...

  4. docker容器composer 部署 laravel框架

    首先yum install docker     安装docker service docker start   启动docker docker pull  docker.io/skiychan/ng ...

  5. Codeforces Round #553 (Div. 2) A题

    题目网址:http://codeforces.com/contest/1151/problem/A 题目大意:给定一个由大写字母构成的字符串和它的长度,有这样的操作,使任意一个字母变成与其相邻的字母, ...

  6. Falsk SqlAlchemy

    pip install mysql-connector from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Fl ...

  7. python+selenium,打开浏览器时报selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH

    有一年多没写web自动化了,今天搭建环境的时候报了一个常见错误,但是处理过程有点闹心,报错就是常见的找不到驱动<selenium.common.exceptions.WebDriverExcep ...

  8. JavaScript并发模型与Event Loop (转载)

    并发模型可视化描述 model.svg 如上图所示,Javascript执行引擎的主线程运行的时候,产生堆(heap)和栈(stack),程序中代码依次进入栈中等待执行, 若执行时遇到异步方法,该异步 ...

  9. 找不到org.restlet.ext.jackson 解决办法

    检出 转成maven工程 ,不过最后发现有两个包maven没有找到: <dependency> <groupId>org.restlet.jse</groupId> ...

  10. propertychange事件导致的IE浏览器堆栈溢出

    前段事件做项目,在IE下测试时,发现会报堆栈溢出的错误,其他浏览器正常,于是开始了苦逼的IE查错路程... 由于是在操作了某个输入框之后才出现的错误,所以把重点放到了input的相关事件,最终发现是这 ...