Archive

Archive for the ‘Delphi’ Category

免费tumblr微博windows客户端(附下载链接和源码)

2011-08-22 留下评论

目前很火的 tumblr 微博,想必各位seoer都是知道的,大部分的人可能都是以给别人红心的方式做外链。其实在 tumblr 上发带链接的图片或者软文,然后被别人liked或者reblog也是一个不错的选择。只是 tumblr 在线发文章或者发图比较麻烦(我比较懒),而国内高手做的即便是收费的也仅局限于自动红心别人,这样就在一定程度上限制了seotumblr 上的发展。

今天推荐一款国外的 tumblr微博windows客户端(下载链接:http://dl.dbank.com/c0omoemxrm)
作者已经开源(源代码下载:http://dl.dbank.com/c0exuxlqsj)

软件是用C#做的。有能力的朋友可以试着增强下。
找了很久只找到这一款,估计是没有人做这个东西。要是能整合上seo的功能那就强大了。

欢迎大家来 我的tumblr 并且 follow me on tumblr

Delphi 2010 lite加装帮助的方法

2011-07-25 留下评论

基于爱好,下载了一个delphi 2010 lite,业余玩玩。

不过这东西是网友重新打包的,没有带帮助。在网上搜索一下加摸索后搞定。步骤如下:

Delphi 2010本身的帮助(MSDN风格的)
1. 下载如下文件:

http://installers.codegear.com.edgesuite.net/update/radstudio/7.0/Help/Update1/Help_Setup.exe
http://installers.codegear.com/release/radstudio/7.0/Help/129/helpemb_english.7zip
http://installers.codegear.com/release/radstudio/7.0/Help/129/help3rdparty.7zip
http://installers.codegear.com/release/radstudio/7.0/Help/129/helpinstall.7zip
http://installers.codegear.com/release/radstudio/7.0/Help/129/helpinstall_english.7zip
http://installers.codegear.com/release/radstudio/7.0/Help/129/helppsdk.7zip

最后那个helpsdk.7zip是Microsoft SDK的帮助文件,比较大,有235M左右,不想安装的话可以不下载。其它文件总共80M左右。

2. 如果机器上没有安装较新版本的MSDN,则需要单独安装Microsoft Document Explorer。我找了份MSDN,在里面找到了DExplore.exe,安装上去可以(里面包含的是MDE 2008,不知道MDE 2005是否可以跑Delphi 2010的帮助)

3. 运行第一项里面下载的Help_Setup.exe,搞定

CHM风格的帮助
也可以从 http://docs.embarcadero.com 下载CHM格式的帮助,然后用下面这个插件来使用

http://cc.embarcadero.com/Item/24815
Help expert For Delphi 2005-2007 which integrates CHM and Winhelp files. (Updated)

虽然说是用于Delphi 2005-2007,但我在Delphi 7和2010上都安装成功了(d7需要添加HtmlHelp()这个API的声明, 网上找HTMLHELP_Decl.pas)

Delphi 2010 lite加装帮助的方法 – 巴蛮子 – 博客园

分类:Delphi 标签:,

在Delphi XE 中使用go语言的并发编程方法

2011-07-23 留下评论

google的go语言最近挺热的, 除了它很酷的语法外,更吸引开发者的是类似coroutine的goroutine,个人觉得它比lua的coroutine更聪明一些,因为它能在运行 时自动组合线程和纤程的能力。另外go语言认为线程间的数据应该通过channel通讯,而不是用地址。这些特点非常方便开发稳定的并发式程序,也提供了 清晰的并发编程思路。

go的channel携带一个数据,用于在多个coroutine之间通讯,它容易控制,因为它的规则很简单:没有值时才可以写,否则suspend,有值时才可以读,否则也suspend,并且读写是成对的操作。

其实go的思想也可以拿到delphi里用,可以用线程模仿goroutine,delphi主要用于客户端开发,所以没有go的高效率也可以接受。下面是一个实际效果的演示,希望它可以给多线程中的delphi程序员提供另一个思路。
在Delphi XE中使用go语言的defer方法例子

在Delphi XE中使用go语言的并发编程方法的例子之二

在Delphi XE中使用go语言的并发编程方法的例子之三

在Delphi XE中使用go语言的defer方法例子

{$APPTYPE CONSOLE}

uses
SysUtils,
coroutineUnit;

begin
TProc(procedure()
var
c: CChannel<Integer>; //声明一个通道,它可以携带一个整型数据。
i: Integer;
begin
c:=CChannel<Integer>.Create;

for i:=1 to 5 do //创建五个任务线程,并立即开始工作。
go(  //在go语言里,有一个go关键字,用于把一个函数以goroutine方式运行,这里使用了go语言的风格,用一个go函数代替。
procedure()
begin
Sleep(1000);   //假设这个任务比较复杂,花费了一秒时间。
c.value:=1;     //任务完成后,给通道一个值,这个值是多少在这个示例里不重要,它仅仅是给出一个信号:我完成了
end);

for i:=1 to 5 do //对这五个任务判定是否已完成
c.value;             //当value有值时,这句才能读到,否则就等待
Writeln(‘全部完成’);
c.Free;
end)();

Readln;
end.


上一篇只提供了一个示例,可能不太容易说明什么,这里再增加一个例子。
{这个示例演示了经典的生产消费问题。
go的教程里就这个问题提供了一个Eratosthenes素数筛选法的例子,这里简化一下,演示筛选偶数吧}

我习惯把begin写成同一行,可能很多人不习惯。而这个问题在go语言里消失了,因为它要求{不能换行。

program demo2;

{$APPTYPE CONSOLE}

uses
SysUtils,
coroutineUnit;

//bug反馈:22140505@qq.com

begin
TProc(procedure()
var
i: Integer;
c: CChannel<Integer>; //声明一个通道,它可以携带一个整数,用于在两个线程之间传递
begin
c:=CChannel<Integer>.Create;
go( //启动生产线程
procedure()
var
i: Integer;
begin
for i:=1 to 10 do //制作10个整数作为产品(好弱。。),交给产生线程
c.value:=i;
c.value:=-1; //为-1时表示生产结束了(这属于这个模型的协议,我随意规定的)
end);
go(  //启动消费线程,它不停的接收整数产品,判断并输出为偶数的值
procedure()
var
i: Integer;
begin
while true do begin //不停的处理,但cpu消耗不高
i:=c.value;  //接收产品,如果没收到,就停在这等
if i=-1 then begin //为-1时表示生产结束了(这属于这个模型的协议,我随意规定的)
c.Free;
break;
end;
if i mod 2=0 then
writeln(inttostr(i));
end;
end);
end)();

Readln;
end.


这个例子演示了如何实现超时控制

program demo3;

{$APPTYPE CONSOLE}

uses
SysUtils,Generics.Collections,
coroutineUnit;

//这个例子演示了如何实现超时控制

var
cWork, cTimeout: CChannel<Integer>; //声明两个通道,各用于工作和超时
ret: tpair<Integer, Integer>; //后面有讲到
begin
cWork:=CChannel<Integer>.create;
cTimeout:=CChannel<Integer>.create;

go(procedure() //起动工作线程
var
i: Integer;
begin
sleep(1010);  //假设这个工作费时1010毫秒
try
cWork.value:=1;  //发通道发送一个值,表示工作完成了。
except
end;
end);

go(procedure()  //起动一个线程用来计时
begin
sleep(1000);  //假设超时等待时间是1秒
cTimeout.value:=1000; //…
end);

{直到cWork,cTimeout这两个通道至少有一个可读取,获取通道的结果,结果是个pair,其中key描述了哪个通道有响应,value描述了通道的值(对这个select的模仿远没有go语言的幽雅,也许以后会有更好的办法)}
ret:=CCoroutine.select<Integer>([cWork, cTimeout]);
case ret.key of  //判断是哪个通道可读
0: Writeln(‘完成’);  //如果是第0个,就是cWork的信号了,表示在超时等待之前工作完成了。
1: Writeln(‘超时’+inttostr(ret.value));  //…
end;

cWork.Free;
cTimeout.Free;
Readln;
end.


在实现函数时,如果中间的步骤出错,需要释放资源并退出函数,这些工作很繁杂,容易出错。 go语言的作者对过去十年软件开发的经历感到失望,针对这个问题,他带来了defer方法,它能让不管在函数内的哪个地方exit,都确保你有机会清扫干 净。Delphi XE中也可实现一个类似的方法。 program demo_defer;

{$APPTYPE CONSOLE}

uses
SysUtils,
coroutineUnit; //还是用这个单元。。。还是在附件里

begin
TProc(procedure()  //这个函数演示将一个文件的内容,拷到另一个文件里
var
f1, f2: Integer;  //两个文件指针,f1的内容要拷到f2里
begin
f1:=FileOpen(‘f1’, fmOpenRead);   //打开f1文件
defer(procedure()  //defer函数将参数函数保存起来,在它所属的函数退出时再调用。
begin
FileClose(f1);
Writeln(‘f1被关闭’);
end);
f2:=FileOpen(‘f2’, fmOpenWrite);  //再打开f2文件
if f2=-1 then begin
Writeln(‘f2打开失败’);
Exit;  //果断退出,不必考虑f1的状态
end;
//copyContent(f1, f2);   //开始copy(假设有这个拷贝函数存在)
FileClose(f2);
end)();

Readln;
end.

以往在处理这种情形时,需要判断f2打开是否失败,如果失败的话需要将f1关闭再退出,如果这个函数很复杂,有可能会忘记关闭,而用这个方法,确保不管你写多少个exit,关闭f1的代码都会被执行到。

实际输出的结果是  :
f2打开失败
f1被关闭

分类:Delphi 标签:, , ,