-
mm要gg切了山药加到汤里一起煲。弄好后mm问gg:“你的手切了山药不麻么?我都得戴手套切呢!”gg说:“没有啊,没觉得山药麻手啊”mm:“你手上的皮真厚!”gg:“那是,你不看我单身了这么多年……”[face27]
-
谨以此文纪念我从少年走的青年的历程;曾经有位大哥告诉过我,年青时代不要总去回忆,眼睛要向前看;
我以为:在必要的时候,回首历程更能体味到不曾体味过的味道,也是一种成长。
1、我的故事之学生时代
很不幸,由于初中之后没有考入重点高中我也就失去了上高中的可能,加入到中专学校的队伍里,
那是1997年发生的事情。得知考上中专以后,我并没有感觉有多少欢乐,我一直想上高中;因此我郁郁不
已,但是综合了很多因素后,我不得不放弃高中——大学这样一条和大多数人一样的道路,而是走了一条
狭长的险峻的小山路。
我们班是学校里最重视的两个班级中的一个,师资配备比较优秀,而且某些课程直接聘请大学老师给
我们直接授课,尽管如此踏入社会以后,还是感觉什么都不会。这是后话,暂且不表。
话说中专二年级时,我的周围相处的比较铁的哥们里面有两个人,C和D。他俩一个比我大,一个比我
小,我们经常一起玩;不知什么时候,小D恋爱了。这小子保密了近半年,年底的时候,我们才知道。后
来C也恋爱了。于是乎变成了五个人,我成了灯泡。每次出去玩,我都不去,但他们总叫上我,不去他们还不高兴,只好不得已而为之。现在想想应该打死也不去。中专里恋爱的风气比较重,但我没有找。我知道自己以后有很长的路要走,这个时候恋爱,是不会有什么结果的;尽管如此快毕业的时候偶还是喜欢上了一个同班女孩,但从来没有表白过。时至今日她已经为人妻,为人母了。如果算数,这应该就算是偶的初恋吧或许算暗恋?不知道,也没研究过。反正是年代久远的事情了。
记得有一次,五个人在河边玩,那里是个开放的公园,他们卿卿我我的只顾他们自己,偶闲来无事于是拿起像机四处寻找可以入眼的景色。忽然发现有几个穿着初中校服的学生在树底下,偶就把相机对准了他们,还没等拍呢就被人家骂了个狗血淋头。好狼狈啊。[face10] -
function StartService(AServName: string): Boolean;
var
SCManager, hService: SC_HANDLE;
lpServiceArgVectors: PChar;
begin
SCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
Result := SCManager <> 0;
if Result then
try
hService := OpenService(SCManager, PChar(AServName), SERVICE_ALL_ACCESS);
Result := hService <> 0;
if (hService = 0) and (GetLastError = ERROR_SERVICE_DOES_NOT_EXIST) then
Exception.Create(’The specified service does not exist’);
if hService <> 0 then
try
lpServiceArgVectors := nil;
Result := WinSvc.StartService(hService, 0, PChar(lpServiceArgVectors));
if not Result and (GetLastError = ERROR_SERVICE_ALREADY_RUNNING) then
Result := True;
finally
CloseServiceHandle(hService);
end;
finally
CloseServiceHandle(SCManager);
end;
end;[face01] -
2006-06-13
TreeView 收藏 - [梦乡的博客]
数据库表TreeView树的快速生成
根据数据表的内容生成TreeView树状结构,通常的做法就是从顶级开始,然后逐项递归查询遍历生成。这种方法在实现上容易做到,也很容易想到,但是效率比较低,因为数据库的检索(SQL语句需要解释执行,而且是对数据库文件进行操作)还是比较耗时的,尤其是树的层次较多,节点较多的情况。这里我要介绍的方法是以空间换取时间,只进行一次数据库检索,提取出全部数据,然后一次生成TreeView树状结构。通过SQL语句,让返回的记录按照父节点ID、节点ID进行排序,这样保证每次当前要添加的节点记录的父节点都已经添加到了TreeView树中,剩下的工作就是如何在TreeView树中找到父节点。这里我采用了一个排序的TStringList列表,通过排序列表采用二分查找的快速性能,就能够很快地查找到当前要添加节点的父节点,从而插入到TreeView树的正确位置。
源代码如下(假定数据表名称为FTree,字段有ID, ParentID, Name):
procedure MakeTree(Query: TQuery; TreeView: TTreeView);
var
List: TStringList;
Node: TTreeNode;
Index: Integer;
begin
TreeView.Items.BeginUpdate;
try
TreeView.Items.Clear;
List := TStringList.Create;
try
List.Sorted := True;
while not Query.Eof do
begin
if Query.FieldByName(’ParentID’).AsInteger = 0 then { ParentID=0,顶层节点 }
Node := TreeView.Items.AddChild(nil, Query.FieldByName(’Name’).AsString)
else
begin
Index := List.IndexOf(Query.FieldByName(’ParentID’).AsString);
Node := TreeView.Items.AddChildFirst(TTreeNode(List.Objects[Index]),
Query.FieldByName(’Name’).AsString);
end;
List.AddObject(Query.FieldByName(’ID’).AsString, Node);
Query.Next;
end;
finally
List.Free;
end;
finally
TreeView.Items.EndUpdate;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
T: DWORD;
begin
T := GetTickCount;
Query1.SQL.Text := ’SELECT * FROM FTree ORDER BY ParentID, ID’;
Query1.Open;
MakeTree(Query1, TreeView1);
Label1.Caption := Format(’MakeTree所用时间: %d ms’, [GetTickCount - T]);
end;
从当前节点的子节点开始查找,并不仅查找子节点,也会遍历同级和父级节点
procedure TFrmWindowView.btnSearchClick(Sender: TObject);
//查找节点内容
function FindChild(
const ANode : TTreeNode;
const AText : string;
const AStart : Integer = 0
):Boolean;
//遍历子节点
var
i : Integer;
begin
Result := False;
for i := AStart to ANode.Count - 1 do
begin
if Pos(AText,UpperCase(ANode.Item[i].Text)) > 0 then
begin
ANode.Item[i].Selected := True;
Result := True;
Exit;
end;
Result := FindChild(ANode.Item[i],AText);
if Result then Exit;
end;
end;
function FindParent(
const ANode : TTreeNode;
const AText : string
):Boolean;
//遍历父节点
begin
Result := False;
if not Assigned(ANode.Parent) then Exit;
Result := FindChild(ANode.Parent,AText,ANode.Index + 1);
if not Result then
Result := FindParent(ANode.Parent,AText);
end;
var
sSearchText : string;
begin
if not Assigned(tv.Selected) or (edtSearch.Text = ’’) then Exit;
sSearchText := UpperCase(edtSearch.Text);
if not FindChild(tv.Selected, sSearchText) then
FindParent(tv.Selected, sSearchText);
end;
仅仅十几行代码实现对TreeView的遍历
------------------------------------------------------
function TForm1.AllOverTreeView(node:TTreenode):TTreenode;
begin
while node<>nil do
begin
if node.HasChildren then
begin
node:=node.getFirstChild;
allovertreeview(node);
node:=node.Parent;
end;
if node.getNextSibling<>nil then
node:=node.getNextSibling
else
exit;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
parentnode:TTreenode;
begin
parentnode:=Mytreeview.Items.GetFirstNode;
AllOverTreeView(parentnode);
end;
------------------------------------------------------
遍历TreeView的方法有很多,我经过反复编程实现,上面是我用最少的代码实现TreeView的遍 -
2006-03-23
主题:低薪年轻人最佳理财路 - [梦乡的博客]
主题:低薪年轻人最佳理财路 小武哥 [转贴 2006-3-23 21:33:52 ]
“定期定额”投资基金之一:何谓定期定额
投资共同基金可以一次单笔购买,也可以每月固定投资一笔钱。“定期定额”就是每隔一段固定时间(一个月或两个月)以固定的金额投资于同一只共同基金。办理定期定额手续非常简单,只要投资人与基金公司或基金代销机构约定每个月(或两个月)固定的时间从其账户中划出固定的金额来投资基金即可。
定期定额这种小额投资方式适合无大笔资金投资但具长期理财需求的人。对于大多数没有时间研究经济景气变化和市场多空的基金投资人而言,“定期定额投资策略”可以说是相当省时省力的投资方法,并且还可以避免不小心买在高点的风险,因此定期定额投资基金常被称为“懒人理财术”、“傻瓜理财术”、“小额投资计划”。
定期定额投资基金方法融合了定期存款“零存整缺的观念,并且还有专家理财、免除自己选股的烦恼。这种兼具储蓄、理财的投资方式,相当适合年轻、刚入社会的上班族。
(字数 : 495 )
评论: 0 | 推荐: 0 | 引用(TrackBack): 0 | 点击: 0 | 收藏
主题:经典的理财理念不可或缺的理财头脑! 小武哥 [转贴 2006-3-23 21:31:31 ]
我们不奢望物欲横流,但也不希望过得清贫淡泊。在当今的社会中我们应当积极地去创造财富、创造美好的未来。首先要确立好自己的目标,不要把财富完全押在运气上面,更不能靠歪门邪道,一个人出生的时候贫穷,责任并不在他,当他老的时候贫穷,就怨不得人了。下面的这些关于理财的理念,有的经典有的新鲜,有了这些理念,你会发现其实财富和自己并不遥远。
“钱装进口袋不如装进脑袋”
知识就是财富,此言不谬,年轻时把钱装进口袋不如装进脑袋,积累财富的途径之一就是提升自我价值,所以为知识进行的投资是值得的,要看长远的收益而不是一时的付出。
“盲目贷款不如量力而行”
“能挣会花”日渐成为最流行的理财新观念。虽说贷款消费能够“花明天的钱圆今天的梦”,可受还款压力影响,有些家庭常常捉襟见肘,甚至引发家庭矛盾。对于不愿承受过大压力的人来说,尽量不贷款或选择所能承受的小额贷款也是不错的选择。
“一人说了算不如夫妻AA制”
对现代人来说,夫妻收入有高有低,双方属于个人自主性的开支越来越大,因此AA制理财方式日渐被一些家庭所接受,这种理财方式能最大限度地发挥个人特长,分散家庭投资风险。同时,财务独立自主也有助于减少矛盾,促进家庭和睦。
(字数 : 624 )
评论: 0 | 推荐: 0 | 引用(TrackBack): 0 | 点击: 0 | 收藏
主题:常见理财五大误区 [荐] 小武哥 [转贴 2006-3-23 21:30:03 ]
第一部分的人生规划已经讲完了,金钱是财富,你的人生就是财富,怎么对人生进行规划?讲了八点,一共是八个人生规划的内容。下面跟大家分享一下常见的理财误区,这是针对年轻人的,比较极端的。
1,月光型,年轻人很常见的,特别冲动,看见什么就想买,把所有钱都花光。
2,进退两难型,虚荣心比较重,跟第一种不同的是特别渴望存钱,对金钱特别矛盾。他理智,但是花钱的时候控制不了自己。
3,无头苍蝇型,很忙,没时间理财。比如说忙了10年,你的钱随便放在活期存款,但是你的钱用10年的时间,如果每年都是10%投资回报的话,本金翻了一倍,十年之后你的财富少掉了一半,因为没有好好规划财富,所以财富流失了都不知道。
4,有心没胆型,心里非常惧怕,对金融机构产品没有信心,觉得太麻烦了,肯定很高深莫测,还是活期吧。
5,狂热财迷型,盼着自己的财产不断增值,把自己每分钱拿去增值,有的时候对投资没有正确的认识。所有的投资有风险,有各种各样的风险。就算你精细规划,也不可能财产不停地增值,每刻每秒不错过任何一次。 这是有比较好玩的理财误区。
(字数 : 533 )
评论: 0 | 推荐: 0 | 引用(TrackBack): 0 | 点击: 0 | 收藏
主题:理财必读之方法篇 小武哥 [转贴 2006-3-23 21:28:22 ]
理财能手起步
说到理财的方法,本应是仁者见仁智者见智,但是对于很多刚刚开始理财的入门者,有些方法非常方便实用,如果掌握了这些基本的方法步骤,就是您成功的第一步。
认清自己
要想理好财,首先就要了解自己的基本情况,到底有多少家产?哪些是固定财产?流动资本有多少?所需还的债务又有多少?有多少可以用来再投资?自己(家庭)平时的总收入是多少?平时的总支出是多少?自己(家庭)处在什么样的社会经济地位?是否掌握了一定的投资方式和投资技能?自己能承受多大的投资亏损?如果您对上面问题思考清楚了,才能认清自己的情况,从而不至于过于盲目。
三大准备
在开始理财之前,您还要做好充分准备,资金、知识和心理三方面的准备工作不可或缺。资金准备指的是您要准备好用于投资的钱,一般来说主要是除日常开支、应急准备金以外的个人流动性资金。然后是知识上的准备 -
2006-02-22
转:一个光棍的呐喊! - [梦乡日记]
转:一个光棍的呐喊!
汽车渴望公路,
花草渴望雨露,
太监迫切渴望著雄性激素。
灵魂渴望超度,
心灵渴望归宿,
而我则迫切渴望著有个媳妇。
众里寻她千百度,
踏平脚下路。
蓦然回首细环顾,
大婶大娘无数。
偶有美女光顾,
还是有夫之妇,
余下大多数,
基本不堪入目。
时间犹如脱兔,
匆匆不肯停步。
转眼就把我拖到了该当爹妈的岁数。
然而上天却挺可恶,
对我不管不顾。
把我培养的庸庸碌碌,
难以获得少女的爱慕。
我曾向月老求助,
求他将我单身的生涯结束。
而他给予我的眷顾,
竟是接踵而至的恶女和怨妇。
比起她们的飞扬跋扈,
以及对我精神上的无情屠戮,
我更愿意选择让步,
甘心走向黄泉之路。
无助,无助。
其实我并非一无是处。
我有很多的优点可以列举和陈述。
但我不知道是什么缘故,
我竟无法得到过别人的敬仰和拥护
我的爱心彰明较著,
最最热心于公益捐助。
为了祖国福利和体育事业的长足进步,、
我不知疲倦的奔波于体彩和福彩中心投注;
为了向世人体现优越的社会主义制度,
以及在党和国家的领导下我们小康的程度,
我毅然决然的增加了喝酒的次数,
终于练出了代表富足的啤酒肚;
我还坚持为人民服务,用我最大的热情为别人提供帮助。
为了让我这片心意落到实处,
我硬是把不愿过去的大娘也搀过了马路……
而我得到的赞扬却远远少于挨骂的次数。
我不明白我的努力换来的为何只是别人的不屑一顾甚至是愤怒。
是因为我过人的天赋,
让他们相形见绌,
还是我高尚的品格和气度,
让他们产生了深深的嫉妒?
我的优秀并没有让我自负,
更没有因为自己的伟大而恃才傲物。
本以为这样才能有女孩对我暗生情素,
谁知我等到现在也还没有一点迹象和眉目。
其实要把女人比做猎物,
我则是一个迷茫的猎户。
因为我实在是不懂狩猎的技术。
该跟著群雄逐鹿,
还是该继续著守株待兔,
思考了很久也没有整理出一条清晰的思路。
也许这便也成了我的桎梏,
成了我无法得到爱情的又一大因素。
或许曾经的某次时机被我奢侈的贻误,
就造成了现在的万劫不复。
咱们这个国度,
人口资源丰富。
但为何娶不到老婆的男人还是不计其数?
是因为封建思想的束缚,
打乱了男女的比例和数目,
还是因为社会的退步,
又重新开始了一夫多妻的制度?
有时想想也他妈愤怒,
你说凭啥大款就可以包养了N个情妇?
难道只为著权利和财富,
就可以不受道德的约束,
并置我们光棍于不顾,
抢占著资源无数?
怪也怪女人们过于世故,
对金钱和地位的趋之若鹜。
只知道花园洋房和别墅,
早把真情的概念颠覆。
冲动时我真恨不得变成动物,
哪怕只是头卖力的牲畜。
听凭主人的吩咐,
不用感受做人的无助。
或者干脆来个移花接木,
彻底的做个变性手术。
跑到人群中滥竽充数,
也好让同胞们多一条可以选择的出路。
街上的婚介星罗棋布。
我也曾幻想著他们能帮我打开销路。
然而最终的结果是让我明白了什么叫认贼作父,
并被婚托儿们榨干了我几年的收入。
吃不著猪蹄儿能看看猪跑也算对我心灵创伤的平复。
所以能看到美女的繁华地段成了我最爱的去处。
每当看著她们迈著款款的猫步,
在我的视线里出出入入,
我总是能感受到久违了的心跳并顺便痛心一下她们的已为人妇。
现实的打击让我鸡肠小肚。
我最看不惯情侣们当众亲密过度。
只要看到有人稍越雷池半步,
我就会上前阻止并提醒他们病出口入。
结果自然不必赘述,
我经常会体验到肢体语言的丰富。
尽管如此我也并没有减少对此事的关注,
反而更觉得有必要加大宣传的攻势和力度。
没有爱的倾注,
我如涸辙之鲋。
这样的生活确实很难让我安之若素。
看著朋友们已为人父,
小生活过的美满和睦,
我又何尝不是深深的羡慕,
并渴望著感情上的脱贫致富?
都说男儿有泪不扑簌,
但那绝对是未到伤心处。
有谁知道泪水已经多少次模糊了我心灵的窗户?
况且咱都是沧海一粟,
凭啥我就不能在爱情的海岸登陆?
只能一口一口的吃著干醋,
被动的尽著晚婚晚育的义务!
人生本来就短促,我又怎能就这样默默的虚度?
为了尽快给自己找一个归宿,
我决心不择手段的全力以赴。
错误,错误。
这种想法最终成了我难逃的劫数。
没想到我一时的慌不择路,
竟上演了那样惨绝人寰的一幕。
那是我走投无路,
勾引了有夫之妇。
谁知道罪行败露,
被人家当场抓住。
只后悔不会武术,
没能够杀出血路。
无奈的任人摆布,
惨遭了打击报复。
他们恼羞成怒,
打得义无反顾。
片刀循环往复,
板砖频频招呼。
我浑身血流如注,
俩腿还不住抽搐。
走错那罪恶一步,
差点就死不瞑目。
恐怖,恐怖。、
真庆幸我还能把命保住。
那场我自导自演的 -
2006-02-09
有感于“别太拿自己当回事” - [梦乡的博客]
有感于“别太拿自己当回事”
初听这句话,是一个同事在茶余饭后对我说得。第一感觉是:这是一种中庸之道。
的确,有些时候对某些事情,就不能以太认真的态度去对待它。比如当你还是一个穷光
蛋的时候,去和百万富翁比谁有钱;凡此种种根本不具备可比性的时候,我们没有必要
去认真对待它。
也有些时候,我感觉“别太拿自己当会事”是一种自卑的想法,有些时候“别太拿
自己当回事”是一种自嘲的说法;还有些时候,我觉得“别太拿自己当回事”是自我的
开脱,纯粹的阿Q精神胜利法。[face27][face27][face27] -
我是一个穷光蛋
有人这样说:“穷,是一种经济状态,贫穷是一种心态”。我也十分同意
这句话。从农家走出来的自己。在碰到某些事情的时候,跟周围的人的价值观十分的不
同;总是免不了以一种在别人看来是“小家子气”换句话来说是“吝啬”的眼光去看待
某个事情。因为我穷。当我在经济上摆脱了以前的贫穷时,我还是会不由自主的这样去
想。故此我真正的体会到了“贫穷是一种心态”的说法。但是我又无法象周围的人一样
去拿钱“潇洒”因为我知道,我留着它,要用在刀刃上。我总是对自己说自己和别人不
一样,没有后备军。一切全靠自己。别人说我小气,那就“小气”吧。坚持自己的理想
和信念,走在自己踏出的小径上......[face07] -
人生不过一个字
有人说,人生是一出悲悲喜喜的戏,是一首飘飘忽忽的歌,是一次上去又下来的登山运动,是一场明明灭灭的烟花……是的,有道理,但听起来,太玄虚;悟起来,太深远;做起来,太复杂。
我说,人生不过一个字。你在走仕途人生吗?官不能当太小,太小了,别人瞧不起,说你没本事,不进步;也不能像某些人那样,不顾一切地削尖脑袋,苦苦钻营地往大当。这样的官当得太大了,不仅需奴颜媚骨,装腔作势,假话连篇,布阵设套,风险重重,甚至祸害百姓,贪污受贿,毁于一旦。所以,必须把握一个字。
你在走商场人生吗?钱不能挣得太少(更不能亏本),太少了难以养家糊口,更别说锦衣玉食了,甚至山盟海誓的情人也会苦笑着离你远去。钱也不能挣得太多,太多了就会生邪。今天花天酒地,明天挥金赌场,后天包二奶被老婆打将上来,再就是被贼盯上,被绑匪瞄准,被毒贩子诱到“下水道”里。所以,必须把握一个字。
你在走爱情人生吗?不能爱得太浅,爱得太浅不是真爱,品尝不到真爱的甜蜜,甚至会脚踩数只船,身许多个人,玷污爱情。也不能爱得太深,爱得太深容易失控,失去自我,诚惶诚恐,笨手笨脚,魅力皆无。对方不但不领情,反而会嫌弃你,进而抛弃你。所以必须把握一个字。
你在走真诚人生吗?不宜太真诚。太真诚了,满腹心机的谦谦君子们反会不相信你,甚至窃笑你太傻,太口无遮拦,太没城府。也不能太不真诚,否则,自己不是成为心理猥琐的小人,就会患上严重的抑郁症,毕竟不吐不快呀!所以,也必须把握一个字。
开车不能太快,也不能太慢。太快了易出车祸,太慢了肯定耗油又耗时。吃饭不能太饱,也不能饿着,否则不是消化不良得胃病,就是营养不够,无精打彩。读书不能太少,也不能读得太杂太滥,读得太少没学问无见识,读得太滥太杂又可能迂腐、木讷,成了十足的书吊子……不能太满,不能太缺,所以,一定要把握一个字。
这个字也许太圆滑,太世故,太中庸,但世事纷繁,人生艰难,只能把握这个字,不得不把握这个字。
朋友,猜猜这是一个什么字啊?!
-
2006-01-13
关于用CANVAS类的绘图。 - [Delphi study]
在DELPHI 为编程者提供了一个灵活的绘图场所, 即本文 所述的CANVAS 类, 在DELPHI 中的很多控件都具有此属性, 使编程者可以在这些的控件的表面随 心所欲的绘图, 这对完善用户界面或者制作一些屏幕特技都有着非凡的作用, 下面举例说明几 种特殊屏幕效果的形成过程。
一、CANVAS 必备基本知识:
1. 具有CANVAS 属性的控件:
TBitmap ,TComboBox ,TDBComboBox ,TDBGrid ,TDBListBox ,TDirectoryListBox ,TDrawGrid ,TFileListBox ,TForm ,THeaderControl ,TImage ,TListBox ,TOutline ,TPaintBox ,TPrinter ,TStatusBar ,TStringGrid 等 ,
2.CANVAS 属性及命令: 篇幅所限, 省略参数及格式说明, 具体请参考文后程序及DELPHI 帮助文件:
canvas.rectangle(): 画矩形 pen.color: 定义画笔颜 色
roundrect(): 画圆角矩形 pen.width: 定义画笔宽度
arc(): 画弧线( 不填 充) brush.color: 定义填充颜色
chord(): 画弧线( 填 充) textout(): 在固定位置输出字符串
pie: 画扇 形 textwidth: 取字符串高度
polygon(): 画多边形填充 textheight: 取字符串宽度
polyline(): 多点连线( 不填充) font.color: 指定字体颜色
Pixels(): 指定固定象素点颜色值 font.size: 指定字体大小
moveto(): 指明画线起 点 Ellipse(): 画圆或椭 圆
lineto(): 指明画线终 点
3. 使用CANVAS 注意事项: 当窗 口进行重画时, 画布上的图像将消失, 比如当窗口进行最小化又重新恢复时,就会引起画布上图 像的消失,另外当刚刚运行程序时,窗口也是属于重新绘制,所以如果在绘制窗口之前在画布上 绘图,弹出窗口后将不能显示出图像,比如在TForm1.FormCreate() 事件中进行画布绘图操作将 是徒劳的,但可以在此事件中进行画布操作的准备工作,比如设置画笔的颜色和宽度等。
二、CANCAS 应用举例:
1. 为控 件增加阴影或投影效果: 基本原理就是在利用该控件的父控件比如FORM 或者其它容器控件 的CANVAS, 在需要修饰的控件周围适当处填加图像, 通过线条及颜色的合理达配, 使控件与周围 的图像融为一体, 形成特殊的视觉效果, 具体操作时需要根据被修饰控件 的TOP、LEFT、WIDTH、HEIGHT 等属性,确定需要画线的起点和终点坐标,这样操作无论被修饰控件 位置及尺寸如何变化,都可以保证投影及阴影效果完美的实现;比如可在窗口中建立三个按钮, 然后在按钮2 和按钮3 的CLICK 事件中填加如下代码, 之后按下按钮2 或按钮3 即使按钮1 形成投影 和阴影效果:
procedure TForm1.Button2Click(Sender: TObject);
var
x,y,i:integer;
begin
x:=0;y:=0;
form1.canvas.pen.width:=1;
for i:=0 to 8 do
begin
form1.canvas.pen.color:=$00a0a0a0;
form1.canvas.moveto(Button1.left+Button1.width+x,
Button1.top+y);
form1.canvas.lineto(Button1.left+Button1.width+x,
Button1.top+button1.height+y);
form1.canvas.pen.color:=$00606060;
form1.canvas.moveto(Button1.left+x,
Button1.top+Button1.height+y);
form1.canvas.lineto(Button1.left+Button1.width+x,
Button1.top+button1.height+y);
x:=x+1;
y:=y+1;
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
x,y,i:integer;
begin
x:=0;y:=0;
form1.canvas.pen.width:=1;
for i:=0 to 8 do
begin
form1.canvas.pen.color:=$00404040;
form1.canvas.moveto(Button1.left+Button1.width+x,
Button1.top+8);
form1.canvas.lineto(Button1.left+Button1.width+x,
Button1.top+button1.height+8);
form1.canvas.moveto(Button1.left+8,
Button1.top+Button1.height+y);
form1.canvas.lineto(Button1.left+Button1.width+8,
Button1.top+button1.height+y);
x:=x+1;
y:=y+1;
end;
end;
2. 为控件加上边框: DELPHI 中有很多控件无边框属性, 利用CANVAS 可以为任意的控件填加边框, 使其轮廓清楚; 具 体操作时, 可先定义出画笔的颜色、画笔的宽度( 边框宽度), 之后用polyline() 命令根据相应控 件的位置、尺寸自动定位四角坐标,一次可完成一个固定宽度矩形的绘制工作,如果需要多种颜 色或者具有立体效果的边框,可多次定义画笔颜色,画出连续的多个矩形,通过调整相邻矩形的 颜色来实现特殊效果的边框绘制工作;比如在窗体中安放两个按钮, 分别在MOUSEMOVE 事件中填 加如下代码, 之后每当鼠标移到相应的按钮上时, 相应的按钮就会出现特殊颜色的边框, 当鼠标 移到窗口空白处时, 则窗口会出现明显的边线, 起到特殊的提示效果;
-
2005-12-25
SQL拾零 - [Delphi study]
Transact_sql:
TRUNCATE TABLE test //用于删除test表中的数据
CREATE FUNCTION //创建用户自定义函数
ALTER FUNCTION //语句修改
DROP FUNCTION //除去用户定义函数
CREATE UNIQUE CLUSTERED INDEX client_id ON clients(client_id)
sql:
(1). group by ... with cube having sum(number)>=40
下面两语句是为了保持前后兼容
compute
compute by
如果使用COMPUTE BY,则必须也使用ORDER BY子句.
(2). JOIN ON 用法
select book.name,tool.name from book JOIN tool ON (boo.id==tool.id)
INNER JOIN ON (内联接:用于消除与另一个表中的任何不匹配的行)
select book.name,tool.name from book JOIN tool ON (boo.id==tool.id)
LEFT OUTER JOIN ON (左外联接:)
FULL OUTER JOIN (完整外部联接:不管另一个表是否有匹配的值,此运算符都包括两个表中所有行)
CROSS JOIN (交叉连接:显示可能的组合)
(3). 使用@@ERROR全局变量处理错误:
SQL Server的所有错误都存储在系统表master.dbo.sysmessages中.用户定义的消息也可以存储在sysmessages中.如果需要,可以使用RAISERROR语句将这些用户定义的错误返回到一个应用程序.若出现一个错误,则返回一条错误信息.
例子: use test
drop table text1
go
create table text1(c1 int,c2 text)
exec sp_tableoption ’text1’,’text in row’,’on’
insert text1 values(1,’This is a text.’)
go
select * from text1
go
(4). 检索ntext,text,image
首先看例题: use test
go
create table text1(c1 int,c2 text)
exec sp_tableoption ’text1’,’text in row’,’on’
insert text1 values(’1’,’This is a text.’)
go
select * from text1
go
有几种方法:
1.在SELECT语句中引用该列
2.使用TEXTTPTR函数
3.使用SUBTRING函数
4.使用PATINDEX函数
例题:
a. exec sp_tableoption ’text1’,’text in row’,’off’
declare @ptrval varbinary(16)
select @ptrval=TEXTPTR(c2)
from text1
READTEXT text1.c2 @ptrval 0 7
b. select substring(c2,1,7) as c2
from text1
c. use text
go
select patindex(’%a%’,c2) as 起始位置
from text1
go
(5).修改ntext,text或image值
可以使用下面的几种方式来修改:
1. 使用数据库API函数;
2. 使用WRITETEXT语句重写该列的整个数据值;
3. 使用UPDATETEXT语句更新ntext,text或image列的特定数据块.
example:
1. use test
go
declare @ptrval varbinary(16)
exec sp_tableoption ’text1’,’text in row’,’off’
select @ptrval=textptr(c2) from text1
writetext text1.c2 @ptrval ’This is a modified text.’
go
select * from text1
go
2. use text
go
declare @ptrval varbinary(16)
select @ptrval=textptr(c2)
from text1
updatetext text1.c2 @ptrval NULL 0 ’this is an inserted text.’
go
select * from text1
go
(6).显示事务:需要显示的定义事务的启动和结束.它是通过BEGIN TRANSACTION,COMMIT TRANSACTION,COMMIT WORK,ROLLBACK TRANSACTION,ROLLBACK WORK 等Transact-SQL语句来完成的.
1.启动事务使用BEGIN TRANSACTION语句.如果遇到错误,以后的语句能自动回滚.
2.结束事务使用COMMIT TRANSACTION语句.该事务中的所有修改都将永久有效.事务占用的资源被释放.
3.回滚事务使用ROLLBACK TRANSACTION清除自事务的起点或到某个保存点所有数据修改.ROLLBACK不释放由事务控制的资源.
4.保存点使用SAVE TRANSACTION语句.如果有条件地取消事务的一部分,事务可以返回的位置.
example:
use bookdb
go
begin tran MyTran --启动事务
insert into book values(9,’Windows 2000 Professional 看图速成’,1,35,’2’)
save tran MySave --保存点
delete book where book_id=9 --删除记录
rollback tran MySave --回滚事务
commit tran
go
select * from book
5. 标记事务用WITH MARK选项使事务名置于事务日志中.将数据库还原到早期状态时,可使用标记事务替代日期和时间.
(7).自动提交事务
(8 -
2005-12-02
win32服务程序的编写(二) - [梦乡的博客]
结论
服务对于Windows NT是很重要的一部分,因为它可让你对操作系统进行扩展。使用列表1的代码作为一个模板,你将会发现要建立一个自己的新服务是非常简单的。
列表1
实现可能是最简单NT服务的代码
//***************************************************************
// From the book "Win32 System Services: The Heart of Windows NT"
// by Marshall Brain
// Published by Prentice Hall
file://
// This code implements the simplest possible service.
// It beeps every 2 seconds, or at a user specified interval.
file://***************************************************************
// beepserv.cpp
#include
#include
#include
#include
#define DEFAULT_BEEP_DELAY 2000
// Global variables
// The name of the service
char *SERVICE_NAME = "BeepService";
// Event used to hold ServiceMain from completing
HANDLE terminateEvent = NULL;
// Handle used to communicate status info with
// the SCM. Created by RegisterServiceCtrlHandler
SERVICE_STATUS_HANDLE serviceStatusHandle;
// The beep interval in ms.
int beepDelay = DEFAULT_BEEP_DELAY;
// Flags holding current state of service
BOOL pauseService = FALSE;
BOOL runningService = FALSE;
// Thread for the actual work
HANDLE threadHandle = 0;
void ErrorHandler(char *s, DWORD err)
{
cout << s << endl;
cout << "Error number: " << err << endl;
ExitProcess(err);
}
// This function consolidates the activities of
// updating the service status with
// SetServiceStatus
BOOL SendStatusToSCM (DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode,
DWORD dwCheckPoint,
DWORD dwWaitHint)
{
BOOL success;
SERVICE_STATUS serviceStatus;
// Fill in all of the SERVICE_STATUS fields
serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwCurrentState = dwCurrentState;
// If in the process of doing something, then accept
// no control events, else accept anything
if (dwCurrentState == SERVICE_START_PENDING)
serviceStatus.dwControlsAccepted = 0;
else
serviceStatus.dwControlsAccepted =
SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_SHUTDOWN;
// if a specific exit code is defined, set up
// the win32 exit code properly
if (dwServiceSpecificExitCode == 0)
serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
else
serviceStatus.dwWin32ExitCode =
ERROR_SERVICE_SPECIFIC_ERROR;
serviceStatus.dwServiceSpecificExitCode =
dwServiceSpecificExitCode;
serviceStatus.dwCheckPoint = dwCheckPoint;
serviceStatus.dwWaitHint = dwWaitHint;
// Pass the status record to the SCM
success = SetServiceStatus (serviceStatusHandle,
&serviceStatus);
return success;
}
DWORD ServiceThread(LPDWORD param)
{
while (1)
{
Beep(200,200);
Sleep(beepDelay);
}
return 0;
}
// Initializes the service by starting its thread
BOOL InitService()
{
DWORD id;
// Start the service’s thread
threadHandle = CreateThread(0, 0,
(LPTHREAD_START_ROUTINE) ServiceThread,
0, 0, &id);
if (threadHandle==0)
return FALSE;
else
{
runningService = TRUE;
return TRUE;
}
}
// Dispatches events received from the SCM
VOID Handler (DWORD controlCode)
{
DWORD currentState = 0;
BOOL success;
switch(controlCode)
{
// There is no START option because
// ServiceMain gets called on a start
// Stop the service
case SERVICE_CONTROL_STOP:
// Tell the SCM what’s happening
success = SendStatusToSCM(SERVICE_STOP_PENDING,
NO_ERROR, 0, 1, 5000);
runningService=FALSE;
// Set the event that is holding ServiceMain
// so that ServiceMain can return
SetEvent(terminateEvent);
return;
// Pause the service
case SERVICE_CONTROL_PAUSE:
if (runningService && !pauseService)
{
// Tell the SCM what’s happening
success = SendStatusToSCM(
SERVICE_PAUSE_PENDING,
NO_ERROR, 0, 1, 1000);
pauseService = TRUE;
SuspendThread(threadHandle);
currentState = SERVICE_PAUSED;
}
break;
// Resume from a pause
case SERVICE_CONTROL_CONTINUE:
if (runningService && pauseService)
{
// Tell the SCM what’s happening
success = SendStatusToSCM(
SERVICE_CONTINUE_PENDING,
NO_ERROR, 0, 1, 10 -
2005-12-02
win32服务程序的编写(一) - [梦乡的博客]
每个操作系统都需要有在后台执行任务的方法,无论是谁正在使用这部机器,这些任务都可以继续运行,后台任务可以处理各种重要的服务,包括系统的或者用户的。例如,一个信使服务可以监控网络,并且在接收到另一台机子的信息时,可以显示一个对话框。一个发送和接收传真的应用需要在启动的时候运行,并且不断地监控负责传真的modem,看有没有传真进来。一个家庭的或者办公室的安全程序,用来控制一件检测设备时,它需要不时地查询传感器,并且在适当的时候响应它。所有这些任务都需要CPU时间来执行它们,不过由于它们需要的CPU时间很少,因此可以放在后台而不影响用户使用系统。
在MS-DOS中,后台的任务是通过TSR(Terminate and Stay Resident)程序来处理的。这些程序经由autoexec.bat文件开始。在UNIX中,后台任务是通过Daemons来处理的。在每次启动UNIX的过程中,你都可以看到操作系统启动一些任务,例如定时的程序(Cron)和Finger的daemons,然后才可以让首个用户登录。在Windows NT中,后台的任务被称为服务。服务可在每次NT启动的时候运行,并且不管是谁登陆,都会一直运行下去。
Windows NT的服务都是通过一般的可执行程序实现的,不同的是,它遵循内部的一个特定协议来设计,以便它们能够与服务控制管理器(SCM,Service Control Manager)进行正确的交互。在这篇文章中,你将学习到如何在Windows NT中创建和安装简单的Win32服务。一旦你懂得了这个简单的服务,你要建立自己的服务也不难了,因为所有的服务,不论是如何地复杂,都必须包含有同样基本的SCM接口代码。只要符合SCM的要求,其实为服务设计的可执行文件和一般的程序并没有多少的区别。
无论是对于编程者或者系统管理员,了解NT的服务如何工作都是很重要的。编程者就不必说了,因为他们要创建自己的服务,而对于系统管理员,也是同样重要的。因为后台的任务可以是很危险的。MS-DOS和Macintosh系统都是一个病毒的温床,因为它们在安全性方面先天不足,它们都可以允许任何人或者程序在任何时间创建后台的任务。Windows NT和UNIX系统是较安全的,因为只有系统管理员才可以为系统增加后台的任务,不过,如果系统管理员加入了一个破坏性的后台程序,就它就可以为所欲为了。因此系统管理员要了解Windows NT服务的技巧和权限设置,就可以避免加入有潜在危险的后台任务。
基本的概念
服务有两种不同的形式。驱动器服务使用驱动器协议,让NT可以与特定的硬件进行通信。另一个是Win32服务,通过一般的Win32 API来实现后台任务。这篇文章的重点是谈Win32服务,因为它们更为常见,而且创建起来也很容易。任何的NT编程者通过使用一般的NT SDK(或者Visual C++),并且可以用管理员的身份访问一台NT机器,都可以实现和安装自己的Win32服务。如果你想创建一些在Windows NT启动时就运行的程序,并且要求它会在系统中一直运行,你就要使用Win32的服务。
在NT中,服务通过控制面板进行管理。在控制面板中,你会发现有一个服务的图标,打开它你会看到所有Win32服务的清单。在那里你可以开始、停止、暂停和继续某个服务。你按下其中的启动按钮后,就会出现一个对话框,你可以修改启动操作以及服务使用的默认帐号。一个服务可以在系统启动的时候自动运行,也可以被完全禁止。或者设置为手动执行。在手动的时候,用户还可以设置启动的参数。要对服务中的项目作修改的话,你需要以一个管理员或者超级用户的身份登录。
Windows NT自带有一些预装的任务,用来处理诸如网络信使服务的操作或者使用“at”命令定时执行的操作,以及分布的RPC命名。在你创建自己的服务时,你必须执行一个独立的安装步骤,以将服务的信息插入到服务管理工具的列表中,这些信息包括有新服务的名字、执行文件的名字和启动的类型等,都会写入到注册表中,这样在机器下次启动的时候,SCM就会得到新服务的相关信息。
创建一个新的服务
执行服务的程序也是一个EXE文件,不过它必须符合某些特定的规范,以便可以与SCM进行正确的交互。微软很细致地设计了函数调用的流程,你必须遵循这些流程,否则你的服务就不能工作。具体的规定如下所列。你可以在Win32编程者的参考指南中找到以下涉及的函数,这些资料在SDK的Win32在线帮助或者Visual C++都有:
.服务的代码必须要有一个一般的main或者WinMain函数。这个函数应该会马上调用StartServiceCrtlDispatcher函数。通过调用这个函数,你可以让SCM得到ServiceMain函数的指针,这样在SCM要启动该服务时,就可以调用它
.在SCM要启动服务的时候,就会调用ServiceMain函数。例如,如果管理员在服务管理器中按下启动的按钮,SCM就会在一个独立的线程中执行ServiceMain函数。ServiceMain应该调用RegisterServiceCtrlHandler函数,这样可以注册一个Handler函数,以便SCM对服务进行控制。Handler函数的名字可以是任意的,不过它会在Handler下的文档中列出来。RegisterServiceCtrlHandler函数会返回一个句柄,在服务需要发送状态信息给SCM时,可以通过该句柄进行。
.Se -
时光总是按捺不住它匆匆的脚步。转瞬之间我作为一颗飘浮的叶子,带着迷惘与幻想,带着希望与理想,飘到到北京这片土地上。
回想起来,那已经是5个月以前的事情了。总也忘不了,离家的那一刻,老父浑浊的目光下,包含了太多的情感,
却是没有说什么只是静静的看着自己的儿子,仿佛在说,雏鹰已经长大,应该去外面的天空下接受风雨的洗礼了。我还
是与往常一样,对老爸说,回去吧。转身,再也没有回头。
汽车开动的一刹那,泪自眼角边汩汩而下。我一直以为男人流泪是没用的表现。想不到还是控制不住自己。它还是流下来了。拭去泪水,对自己说,一定要混出个人样来,否则还有什么脸面回家面对父老。心慢慢地平静下来,思绪被汽车的马达声带向远方……带向了那让我向往的地方。[face29] -
2005-10-24
Delphi下的多线程程序设计 - [Delphi study]
DELPHI32下的多线程程序设计
我们知道,win95或winNT都是“多线程”的操作系统,在DELPHI2.0中,我们可以充分利用这一特性,编写出“多线程”的应用程序。
对以往在DOS或16位windows下写程序的人来说,“多线程”仍然是陌生的,但如同以前我们从DOS下的单任务过渡到windows3.1下的多任务,如今我们又必须过渡到“多线程”领域,毕竟计算机时代是在不断发展的。不过,幸运的是,在DELPHI2.0下进行多线程程序设计并不需要我们去学习庞大的WIN32API函数,我们可以利用DELPHI下标准的多线程类TThread来完成我们的工作。
TThread是一个abstract(抽象)类,也就是说,并不需要根据TThread来声明变量(而且根据TThread声明的变量也是完全无用),我们要做的是把TThread作为基类,用继承的形式来生成子类。实际上,根据TThread来写多线程应用程序是非常容易的。
下面就是一个基本的继承TThread生成的多线程类。
QuerThrd.Pas
unitQuerThrd;
interface
uses
Classes,DBTables;
type
TQueryThreadΚclass(TThread)
private
fQuery:tQuery;
protected
procedureExecute;override;
public
constructorCreate(Suspended:Boolean;Query:
TQuery);
end;
implementation
constructor
TQueryThread.Create(Suspended:Boolean;Quer
y:TQuery);
begin
inheritedCreate(Suspended);
fQuery:ΚQuery;
FreeOnTerminate:ΚTrue;
end;
procedureTQueryThread.Execute;
begin
fQuery.Open;
end;
end.
在上面这个简单的例子中,我们构造了一个TThread的子类TQuery -
2005-10-24
用delphi程序设置系统时间的一个小函数。 - [Delphi study]
Set system date and time
2004-10-18 00:55:05 共享軟件@-0UWw 复制 评论
Set system date and time
With the procedure SetDateTime you can set the date and time of the operating
system, from within your Delphi application.
In the interface-section you define the procedure:
procedure SetDateTime(Year, Month, Day, Hour, Minu, Sec, MSec: Word);
In the ’implementation’ you write...:
{ SetDateTime sets the date and time of the operating system }
procedure SetDateTime(Year, Month, Day, Hour, Minu, Sec, MSec: Word);
var
NewDateTime: TSystemTime;
begin
FillChar(NewDateTime, sizeof(NewDateTime), #0);
NewDateTime.wYear := Year;
NewDateTime.wMonth := Month;
NewDateTime.wDay := Day;
NewDateTime.wHour := Hour;
NewDateTime.wMinute := Minu;
NewDateTime.wSecond := Sec;
NewDateTime.wMilliseconds := MSec;
SetLocalTime(NewDateTime);
end; -
2005-06-09
一个转换货币的函数 - [Delphi study]
function NumToChar(const n: Real): string; //可以到万亿,并且可以随便扩大范围
const cNum: WideString = ’零壹贰叁肆伍陆柒捌玖--万仟佰拾亿仟佰拾万仟佰拾元角分’;
cCha:array[0..1, 0..12]of string =
(( ’零元’,’零拾’,’零佰’,’零仟’,’零万’,’零亿’,’亿万’,’零零零’,’零零’,’零万’,’零亿’,’亿万’,’零元’),
( ’元’,’零’,’零’,’零’,’万’,’亿’,’亿’,’零’,’零’,’万’,’亿’,’亿’,’元’));
var i : Integer;
sNum,sTemp : WideString;
begin
result :=’’;
sNum := format(’%15d’,[round(n * 100)]);
for i := 0 to 14 do
begin
stemp := copy(snum,i+1,1);
if stemp=’ ’ then continue
else result := result + cNum[strtoint(stemp)+1] + cNum[i+13];
end;
for i:= 0 to 12 do
Result := StringReplace(Result, cCha[0,i], cCha[1,i], [rfReplaceAll]);
if pos(’零分’,result)=0
then Result := StringReplace(Result, ’零角’, ’零’, [rfReplaceAll])
else Result := StringReplace(Result, ’零角’,’整’, [rfReplaceAll]);
Result := StringReplace(Result, ’零分’,’’, [rfReplaceAll]);
end; -
来自csdn 作者rivershan
DLL(Dynamic Link Libraries)专题:
比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。在构造软件系统时,如果将所有模块的源代码都静态编译到整个应用程序EXE文件中,会产生一些问题:一个缺点是增加了应用程序的大小,它会占用更多的磁盘空间,程序运行时也会消耗较大的内存空间,造成系统资源的浪费;另一个缺点是,在编写大的EXE程序时,在每次修改重建时都必须调整编译所有源代码,增加了编译过程的复杂性,也不利于阶段性的单元测试。
Windows系统平台上提供了一种完全不同的较有效的编程和运行环境,你可以将独立的程序模块创建为较小的DLL(Dynamic Linkable Library)文件,并可对它们单独编译和测试。在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。这种方式不仅减少了EXE文件的大小和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序使用。Windows自己就将一些主要的系统功能以DLL模块的形式实现。
一般来说,DLL是一种磁盘文件,以.DLL、.DRV、.FON、.SYS和许多以.EXE为扩展名的系统文件都可以是DLL。它由全局数据、服务函数和资源组成,在运行时被系统加载到进程的虚拟空间中,成为调用进程的一部分。如果与其它DLL之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。DLL模块中包含各种导出函数,用于向外界提供服务。DLL可以有自己的数据段,但没有自己的堆栈,使用与调用它的应用程序相同的堆栈模式;一个DLL在内存中只有一个实例;DLL实现了代码封装性;DLL的编制与具体的编程语言及编译器无关。
在Win32环境中,每个进程都复制了自己的读/写全局变量。如果想要与其它进程共享内存,必须使用内存映射文件或者声明一个共享数据段。DLL模块需要的堆栈内存都是从运行进程的堆栈中分配出来的。Windows在加载DLL模块时将进程函数调用与DLL文件的导出函数相匹配。Windows操作系统对DLL的操作仅仅是把DLL映射到需要它的进程的虚拟地址空间里去。DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有.
一、关于调用方式:
1、静态调用方式:由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(如还有其它程序使用该DLL,则Windows对DLL的应用记录减1,直到所有相关程序都结束对该DLL的使用时才释放它),简单实用,但不够灵活,只能满足一般要求。
隐式的调用:需要把产生动态连接库时产生的.LIB文件加入到应用程序的工程中,想使用DLL中的函数时,只须说明一下。隐式调用不需要调用LoadLibrary()和FreeLibrary()。程序员在建立一个DLL文件时,链接程序会自动生成一个与之对应的LIB导入文件。该文件包含了每一个DLL导出函数的符号名和可选的标识号,但是并不含有实际的代码。LIB文件作为DLL的替代文件被编译到应用程序项目中。当程序员通过静态链接方式编译生成应用程序时,应用程序中的调用函数与LIB文件中导出符号相匹配,这些符号或标识号进入到生成的EXE文件中。LIB文件中也包含了对应的DLL文件名(但不是完全的路径名),链接程序将其存储在EXE文件内部。当应用程序运行过程中需要加载DLL文件时,Windows根据这些信息发现并加载DLL,然后通过符号名或标识号实现对DLL函数的动态链接。所有被应用程序调用的DLL文件都会在应用程序EXE文件加载时被加载在到内存中。可执行程序链接到一个包含DLL输出函数信息的输入库文件(.LIB文件)。操作系统在加载使用可执行程序时加载DLL。可执行程序直接通过函数名调用DLL的输出函数,调用方法和程序内部其他的函数是一样的。
2、动态调用方式:是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,使用上较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。
显式的调用:是指在应用程序中用LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态连接库调进来,动态连接库的文件名即是上面两个函数的参数,再用GetProcAddress()获取想要引入的函数。自此,你就可以象使用如同本应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态连接库。直接调用Win32 的LoadLibary函数,并指定DLL的路径作为参数。LoadLibary返回HINSTANCE参数,应用程序在调用GetProcAddress函数时使用这一参数。GetProcAddress函数将符号名或标识号转换为DLL内部的地址。程序员可以决定DLL文件何时加载或不加载,显式链接在运行时决定加载哪个DLL文件。使用DLL的程序在使用之前必须加载(LoadLibrary)加载DLL从而得到一个DLL模块的句柄,然后调用GetProcAddress函数得到输出函数的指针,在退出之前必须卸载DLL(FreeLibrary)。
Windows将遵循下面的搜索顺序来定位DLL:
1.包含EXE文件的目录,
2.进程的当前工作目录,
3.Windows系统目录,
4.Windows目录,
5 -
2005-06-03
关于TClientDataSet 转贴自大富翁KeyLife的日记 - [Delphi study]
KeyLife富翁笔记
作者 -
火车随记
前几天因公出差,路途较远。遂买一硬卧。
候车、上车之辛苦自不必说。单说列车行驶途中,晚饭——熄灯这段时间吧。
自打中午上车,互不相识的人们此时已经默默地共同经历了四五个小时的旅程,随着人们相互之间的了解,车厢里的气氛渐渐活跃了起来。
我是在六车9号的上铺。对面是一位年青貌美的女孩。她的下铺是一位穿着从两三年前到现在都比较前卫的乞丐服的年青女子,全身这一块补丁,那一块补丁的,裸露着黝黑、健康的皮肤。大家正在讨论着一个有趣的话题。后来那个前卫女孩说自己是*少数民族。大家都很惊奇。因为习惯啊、风俗的方方面面的不同,平时大家对这些方面关注的比较少,也都有好奇心,于是问这问那的。我想,大家这样问或许是不太礼貌,但也是好奇嘛,可以理解。但是她的回答呢就明显地有了敌意。好像是大家都在说她的民族的不好似的。每回答一个问题,总是先考虑的就是她们的民族是多么的好。这不是她们民族的不好。是汉族的不好——其实我觉得她没有必要这么做。大家又不是在搞种族歧视,只不过想多了解一点她们的民俗啊,生活习惯啊什么得,至于这么紧张么?
张嘴第一句话就是:这不是*族的不好啊。天呐,我感觉这明显的就是:是不是他们(少数民族)都有自卑心理啊??
-
[glow=255,red,2]经验主义害死人![/glow]
出差回来的路上,本来计划好从通化-大连,在火车上买好船票,8:09分到大连,然后8:50的船去烟台,前后衔接紧密,不用苦苦的等车或等船,想来是多么惬意的一件事情啊!我想大多数朋友是我一样,尤其是经常出差的朋友,对于等车,等船的感受简直是可以用"深恶疼绝"来形容了.
在火车上顺利到买到了船票,虽然她们说大连火车站口有免费接送到港口的车辆,尽管我每次都找不到,偶尔一次找到了还要交钱,所以干脆不理它,直接打的到了港口.到达港口的时候是8:40分,太棒了.心里想到.于是乎不慌不忙得去检票口检票,晃晃悠悠的跟着一群人上了一辆开往船坞.此时停了两辆车,只有一辆是去烟台的船坞的.这是我后来才知道的.
不一会儿,到了船坞,我不紧不慢地晃到了登舱梯边,问旁边的一位警察,警察说你怎么跑这里来了?这是去威海的船!
这一下仿佛一个晴天霹雳,把我惊醒了.一看表天啊,已经8:48了,还有两分钟船就要开了!我怎么办?我的船在哪儿?
时间无多,赶紧找载我来的车,让他把我送过去!车找到了,人却没了,不知道去哪儿了.我的汗一会儿就把全身湿透了.
这时我背起背包,一个劲地跑,虽然我头脑清醒地认识到已经晚了,但是就是不想放弃,心想或许还有一点点希望吧.一路狂奔回到了我上车的地方.然而属于我要登的船在哪儿?我不知道.只好求助于一个人民公仆.这位公仆告诉我说这张船票废了.
此时我所有的希望全部泡汤.虽然失望,但还是接受了这个事实.只好掏毛毛另买了一班中午的船票了.[face27][face27] -
1) I love you not because of who you are, but because of who I am when I am with you.
我爱你,不是因为你是一个怎样的人,而是因为我喜欢与你在一起时的感觉。
2) No man or woman is worth your tears, and the one who is, won‘t make you cry.
没有人值得你流泪,值得让你这么做的人不会让你哭泣。
3) The worst way to miss someone is to be sitting right beside them knowing you can‘t have them.
失去某人,最糟糕的莫过于,他近在身旁,却犹如远在天边。
4) Never frown, even when you are sad, because you never know who is falling in love with your smile.
纵然伤心,也不要愁眉不展,因为你不知是谁会爱上你的笑容。
5) To the world you may be one person, but to one person you may be the world.
对于世界而言,你是一个人;但是对于某个人,你是他的整个世界。
6) Don‘t waste your time on a man/woman, who isn‘t willing to waste their time on you.
不要为那些不愿在你身上花费时间的人而浪费你的时间。
7) Just because someone doesn‘t love you the way you want them to, doesn‘t mean they don‘t love you with all they have.
爱你的人如果没有按你所希望的方式来爱你,那并不代表他们没有全心全意地爱你。
8) Don‘t try so hard, the best things come when you least expect them to.
不要着急,最好的总会在最不经意的时候出现。
9) Maybe God wants us to meet a few wrong people before meeting the right one, so that when we finally meet the person, we will know how to be grateful.
在遇到梦中人之前,上天也许会安排我们先遇到别的人;在我们终于遇见心仪的人时,便应当心存感激。
10) Don‘t cry because it is over, smile because it happened.
不要因为结束而哭泣,微笑吧,为你的曾经拥有。
[face10][face10][face34] -
2005-01-23
Delphi 技巧大集粹5 - [Delphi study]
Dll(动态链接库)学习笔记 选择自 lithe 的 Blog [2005-1-14]
Dll(动态链接库)学习笔记 选择自 lithe 的 Blog
关键字 Dll(动态链接库)学习笔记
出处
DLL(Dynamic Link Libraries)专题:
比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。在构造软件系统时,如果将所有模块的源代码都静态编译到整个应用程序EXE文件中,会产生一些问题:一个缺点是增加了应用程序的大小,它会占用更多的磁盘空间,程序运行时也会消耗较大的内存空间,造成系统资源的浪费;另一个缺点是,在编写大的EXE程序时,在每次修改重建时都必须调整编译所有源代码,增加了编译过程的复杂性,也不利于阶段性的单元测试。
Windows系统平台上提供了一种完全不同的较有效的编程和运行环境,你可以将独立的程序模块创建为较小的DLL(Dynamic Linkable Library)文件,并可对它们单独编译和测试。在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。这种方式不仅减少了EXE文件的大小和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序使用。Windows自己就将一些主要的系统功能以DLL模块的形式实现。
一般来说,DLL是一种磁盘文件,以.DLL、.DRV、.FON、.SYS和许多以.EXE为扩展名的系统文件都可以是DLL。它由全局数据、服务函数和资源组成,在运行时被系统加载到进程的虚拟空间中,成为调用进程的一部分。如果与其它DLL之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。DLL模块中包含各种导出函数,用于向外界提供服务。DLL可以有自己的数据段,但没有自己的堆栈,使用与调用它的应用程序相同的堆栈模式;一个DLL在内存中只有一个实例;DLL实现了代码封装性;DLL的编制与具体的编程语言及编译器无关。
在Win32环境中,每个进程都复制了自己的读/写全局变量。如果想要与其它进程共享内存,必须使用内存映射文件或者声明一个共享数据段。DLL模块需要的堆栈内存都是从运行进程的堆栈中分配出来的。Windows在加载DLL模块时将进程函数调用与DLL文件的导出函数相匹配。Windows操作系统对DLL的操作仅仅是把DLL映射到需要它的进程的虚拟地址空间里去。DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有.
一、关于调用方式:
1、静态调用方式:由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(如还有其它程序使用该DLL,则Windows对DLL的应用记录减1,直到所有相关程序都结束对该DLL的使用时才释放它),简单实用,但不够灵活,只能满足一般要求。
隐式的调用:需要把产生动态连接库时产生的.LIB文件加入到应用程序的工程中,想使用DLL中的函数时,只须说明一下。隐式调用不需要调用LoadLibrary()和FreeLibrary()。程序员在建立一个DLL文件时,链接程序会自动生成一个与之对应的LIB导入文件。该文件包含了每一个DLL导出函数的符号名和可选的标识号,但是并不含有实际的代码。LIB文件作为DLL的替代文件被编译到应用程序项目中。当程序员通过静态链接方式编译生成应用程序时,应用程序中的调用函数与LIB文件中导出符号相匹配,这些符号或标识号进入到生成的EXE文件中。LIB文件中也包含了对应的DLL文件名(但不是完全的路径名),链接程序将其存储在EXE文件内部。当应用程序运行过程中需要加载DLL文件时,Windows根据这些信息发现并加载DLL,然后通过符号名或标识号实现对DLL函数的动态链接。所有被应用程序调用的DLL文件都会在应用程序EXE文件加载时被加载在到内存中。可执行程序链接到一个包含DLL输出函数信息的输入库文件(.LIB文件)。操作系统在加载使用可执行程序时加载DLL。可执行程序直接通过函数名调用DLL的输出函数,调用方法和程序内部其他的函数是一样的。
2、动态调用方式:是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,使用上较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。
显式的调用:是指在应用程序中用LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态连接库调进来,动态连接库的文件名即是上面两个函数的参数,再用GetProcAddress()获取想要引入的函数。自此,你就可以象使用如同本应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态连接库。直接调用Win32 的LoadLibary函数,并指定DLL的路径作为参数。LoadLibary返回HINSTANCE参数,应用程序在调用GetProcAddress函数时使用这一参数。GetProcAddress函数将符号名或标识号转换为DLL内部的地址。程序员可以决定DLL文件何时加载或不加载,显式链接在运行时决定加载哪个DLL文件。使用DLL的程序在使用之前必须加载(LoadLibrary)加载DLL从而得到一个DLL模块的句柄,然后调用GetProcAddress函数得到输出函数的指针,在退出之前必须卸载DLL(FreeLibrary)。
-
2005-01-23
Delphi 技巧大集粹4 - [Delphi study]
DELPHI基础开发技巧 选择自 FlyHope2005 的 Blog [2005-1-14]
DELPHI基础开发技巧 选择自 FlyHope2005 的 Blog
关键字 DELPHI基础开发技巧
出处
DELPHI基础开发技巧
◇[DELPHI]网络邻居复制文件
uses shellapi;
copyfile(pchar(’newfile.txt’),pchar(’//computername/direction/targer.txt’),false);
◇[DELPHI]产生鼠标拖动效果
通过MouseMove事件、DragOver事件、EndDrag事件实现,例如在PANEL上的LABEL:
var xpanel,ypanel,xlabel,ylabel:integer;
PANEL的MouseMove事件:xpanel:=x;ypanel:=y;
PANEL的DragOver 事件:xpanel:=x;ypanel:=y;
LABEL的MouseMove事件:xlabel:=x;ylabel:=y;
LABEL的EndDrag 事件:label.left:=xpanel-xlabel;label.top:=ypanel-ylabel;
◇[DELPHI]取得WINDOWS目录
uses shellapi;
var windir:array[0..255] of char;
getwindowsdirectory(windir,sizeof(windir));
或者从注册表中读取,位置:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion
SystemRoot键,取得如:C:\WINDOWS
◇[DELPHI]在FORM或其他容器上画线
var x,y:array [0..50] of integer;
canvas.pen.color:=clred;
canvas.pen.style:=psDash;
form1.canvas.moveto(trunc(x[i]),trunc(y[i]));
form1.canvas.lineto(trunc(x[j]),trunc(y[j]));
◇[DELPHI]字符串列表使用
var tips:tstringlist;
tips:=tstringlist.create;
tips.loadfromfile(’filename.txt’);
edit1.text:=tips[0];
tips.add(’last line addition string’);
tips.insert(1,’insert string at NO 2 line’);
tips.savetofile(’newfile.txt’);
tips.free;
◇[DELPHI]简单的剪贴板操作
richedit1.selectall;
richedit1.copytoclipboard;
richedit1.cuttoclipboard;
edit1.pastefromclipboard;
◇[DELPHI]关于文件、目录操作
Chdir(’c:\abcdir’);转到目录
Mkdir(’dirname’);建立目录
Rmdir(’dirname’);删除目录
GetCurrentDir;//取当前目录名,无’\’
Getdir(0,s);//取工作目录名s:=’c:\abcdir’;
Deletfile(’abc.txt’);//删除文件
Renamefile(’old.txt’,’new.txt’);//文件更名
ExtractFilename(filelistbox1.filename);//取文件名
ExtractFileExt(filelistbox1.filename);//取文件后缀
◇[DELPHI]处理文件属性
attr:=filegetattr(filelistbox1.filename);
if (attr and faReadonly)=faReadonly then ... //只读
if (attr and faSysfile)=faSysfile then ... //系统
if (attr and faArchive)=faArchive then ... //存档
if (attr and faHidden)=faHidden then ... //隐藏
◇[DELPHI]执行程序外文件
WINEXEC//调用可执行文件
winexec(’command.com /c copy *.* c:\’,SW_Normal);
winexec(’start abc.txt’);
ShellExecute或ShellExecuteEx//启动文件关联程序
function executefile(const filename,params,defaultDir:string;showCmd:integer):THandle;
ExecuteFile(’C:\abc\a.txt’,’x.abc’,’c:\abc\’,0);
ExecuteFile(’http://tingweb.yeah.net’,’’,’’,0);
ExecuteFile(’mailto:tingweb@wx88.net’,’’,’’,0);
◇[DELPHI]取得系统运行的进程名
var hCurrentWindow:HWnd;szText:array[0..254] of char;
begin
hCurrentWindow:=Getwindow(handle,GW_HWndFrist);
while hCurrentWindow <> 0 do
begin
if Getwindowtext(hcurrnetwindow,@sztext,255)>0 then listbox1.items.add(strpas(@sztext));
hCurrentWindow:=Getwindow(hCurrentwindow,GW_HWndNext);
end;
end;
◇[DELPHI]关于汇编的嵌入
Asm End;
可以任意修改EAX、ECX、EDX;不能修改ESI、EDI、ESP、EBP、EBX。
◇[DELPHI]关于类型转换函数
FloatToStr//浮点转字符串
FloatToStrF//带格式的浮点转字符串
IntToHex//整数转16进制
TimeToStr
DateToStr
DateTimeToStr
FmtStr//按指定格式输出字符串
FormatDateTime(’YYYY-MM-DD,hh-mm-ss’,DATE);
◇[DELPHI]字符串的过程和函数
Insert(obj,target,pos);//字符串target插入在pos的位置。如插入结果大于target最大长度,多出字符将被截掉。如Pos在255以外,会产生运行错。例如,st:=’Brian’,则Insert(’OK’,st,2)会使st变为’BrOKian’。
Delete(st,pos,Num);//从st串中的pos(整型)位置开始删去个数为Num(整型)个字符的子字串。例如,st:=’Brian’,则Delete(st,3,2)将变为Brn。
Str(value,st);//将数值value(整型或实型)转换成字符串放在st中。例如,a=2.5E4时,则str(a:10,st)将使st的值为’ 25000’。
Val(st,var,code);//把字符串表达式st转换为对应整型或实型数值,存放在var中。St必须是一个表示数值的字符串,并符合数值常数的规则。在转换过程中,如果没有检测出错误,变量code置为0,否则置为第一个出错字符的位置。例如,st:=25.4E3,x是一个实型变量,则val(st,x,code)将使X值为25400,code值为0。
Copy(st.pos.num);//返回st串中一个位置pos(整型)处开始的,含有num(整 -
2005-01-23
Delphi 技巧大集粹1 - [Delphi study]
# DecodeDate, DecodeTime Example
--------------------------------------------------------
DecodeTime 将TDateTime型态的时间变数,转为Word型态.
--------------------------------------------------------
Unit SysUtils
函数原型 procedure DecodeDate(Date: TDateTime; var Year, Month,Day: Word);
函数原型 procedure DecodeTime(Time: TDateTime; var Hour, Min, Sec,MSec: Word);
范例 procedure TForm1.Button1Click(Sender: TObject);
var
Present: TDateTime;
Year, Month, Day, Hour, Min, Sec, MSec: Word;
begin
Present:= Now;
DecodeDate(Present, Year, Month, Day);
Label1.Caption := ’Today is Day ’ + IntToStr(Day) + ’ of
Month ’ + IntToStr(Month) + ’ of Year ’ + IntToStr(Year);
DecodeTime(Present, Hour, Min, Sec, MSec);
Label2.Caption := ’The time is Minute ’ +IntToStr(Min) + ’ of
Hour ’ + IntToStr(Hour);
end;
--------------------------------------------------------
EncodeDate 将Word型态的日期变数,转为TDateTime型态.
--------------------------------------------------------
范例
procedure TForm1.Button1Click(Sender: TObject);
var
MyDate: TDateTime;
begin
MyDate := EncodeDate(StrToInt(Edit1.Text), StrToInt(Edit2.Text), StrToInt(Edit3.Text));
Label1.Caption := DateToStr(MyDate);
end;
-------------------------------------------------------
EncodeTime 将Word型态的时间变数,转为TDateTime型态.
--------------------------------------------------------
Unit SysUtils
函数原型 function EncodeDate(Year, Month, Day: Word): TDateTime;
函数原型 function EncodeTime(Hour, Min, Sec, MSec: Word):
TDateTime;
范例 procedure TForm1.Button1Click(Sender: TObject);
var
MyDate: TDateTime;
MyTime: TDateTime;
begin
MyDate := EncodeDate(83, 12, 31);
Label1.Caption := DateToStr(MyDate);
MyTime := EncodeTime(0, 45, 45, 7);
Label2.Caption := TimeToStr(MyTime);
end;
范例
procedure TForm1.Button1Click(Sender: TObject);
var
MyTime: TDateTime;
begin
MyTime := EncodeTime(0, 45, 45, 7);
Label1.Caption := TimeToStr(MyTime);
end;
--------------------------------------------------------
FormatDateTime 将日期时间依Format的格式转换给一字串.
--------------------------------------------------------
Unit SysUtils
函数原型 function FormatDateTime(const Format: string; DateTime:
TDateTime): string;
**** 类似DateTimeToString.
Format格式
c 内定值ShortDateFormat的格式.(1996/12/20 09:20:15 PM).
d 日期,前面不补0.(1-31)
dd 日期,前面补0.(01-31)
ddd 星期.(星期日).
Dddd 中文2.01版,同上.
ddddd 日期.(1996/12/20)
dddddd 日期.(1996年12月20日)
m 月份,前面不补0.(1-12)
mm 月份,前面补0.(01-12)
mmm 中文显示.(十二月)
mmmm 中文2.01版,同上.
Yy 年度.(00-99)
yyyy 年度.(0000-9999)
h 小时.(0-23)
hh 小时.(00-23)
n 分钟.(0-59)
nn 分钟.(00-59)
s 秒钟.(0-59)
ss 秒钟.(00-59)
t 时间.(09:20 PM)
tt 时间.(09:20:15 PM)
am/pm 单独显示am or pm.(若大写,则显示大写)
a/p 单独显示a or p.
范例
The following example assigns ’The meeting is on Wednesday, February 15, 1995 at 10:30 AM’ to the string variable S.
S := FormatDateTime(’"The meeting is on " dddd, mmmm d, yyyy, " at " hh:mm AM/PM’,
StrToDateTime(’2/15/95 10:30am’));//???
--------------------------------------------------------
Now 传回目前的日期时间.
--------------------------------------------------------
Unit SysUtils
函数原型 function Now: TDateTime;
范例
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := DateTimeToStr(Now);
end;
# Now, DateTimeToStr Example
--------------------------------------------------------
StrToDate 将字串转为TDateTime型态的日期.
--------------------------------------------------------
Unit SysUtils
函数原型 function StrToDate(const S: string): TDateTime;
范例 procedure TForm1.Button1Click(Sender: TObject);
var
ADate: TDateTime;
begin
ADate := StrToDate(Edit1.Text);
Label1.Caption := DateToStr(ADate);
end;
范例
procedure TForm1.Button1Click(Sender: TObject);
var
ADate: TDateTime;
days: array[1..7] of string;
begin -
2005-01-23
Delphi 技巧大集粹2 - [Delphi study]
发表看法 浏览:11 回复:0
DELPHI常用函数集及简要范例 (2) [2005-1-14]
====================================
File-management routines 档案管理常式
====================================
--------------------------------------------------------
ChangeFileExt 变更档案的副档名
--------------------------------------------------------
Unit SysUtils
函数原型 function ChangeFileExt(const FileName, Extension: string):
string;
范例 procedure TForm1.Button1Click(Sender: TObject);
var
S: String;
P1:String;
P2:String;
begin
P1:=’abc.txt’;
P2:=’.ini’;
S := ChangeFileExt(P1,P2);
Label1.Caption:=S;
end;
结果 S== ’abc.ini’
P1:=’abc’
P2:=’.ini’
S== ’abc.ini’
P1:=’c:\windows\abc.txt’
P2:=’.ini’
S==’c:\windows\abc.ini’
P1:=’abc.txt’
P2:=’ini’
S==’abcini’
**注意:P2的第一位元必须有一点’.ini’
范例
procedure TForm1.ConvertIcon2BitmapClick(Sender: TObject);
var
s : string;
Icon: TIcon;
begin
OpenDialog1.DefaultExt := ’.ICO’;
OpenDialog1.Filter := ’icons (*.ico)|*.ICO’;
OpenDialog1.Options := [ofOverwritePrompt, ofFileMustExist, ofHideReadOnly ];
if OpenDialog1.Execute then
begin
Icon := TIcon.Create;
try
Icon.Loadfromfile(OpenDialog1.FileName);
s:= ChangeFileExt(OpenDialog1.FileName,’.BMP’);
Image1.Width := Icon.Width;
Image1.Height := Icon.Height;
Image1.Canvas.Draw(0,0,Icon);
Image1.Picture.SaveToFile(s);
ShowMessage(OpenDialog1.FileName + ’ Saved to ’ + s);
finally
Icon.Free;
end;
end;
end;
# SaveToFile, Create, Height, Width, Canvas, ChangeFileExt example
--------------------------------------------------------
ExpandFileName 将档案名称加在目前所在之路径全名之後
--------------------------------------------------------
Unit SysUtils
函数原型 function ExpandFileName(const FileName: string): string;
说明 设目前目录为 c:\windows 档案名称为 abc.txt
则结果为 c:\windows\abc.txt
**** 此函数并不是求abc.txt的所在路径.
范例 procedure TForm1.Button1Click(Sender: TObject);
var
S: String;
begin
S:=ExpandFileName(’abc.txt’);
Label1.Caption:=S;
end;
范例
procedure TForm1.Button1Click(Sender: TObject)
begin
ListBox1.Items.Add(ExpandFileName(Edit1.Text));
end;
------------------------------------------------------------------
DirectoryExists 目录是否存在------------------------------------------------------------------
Unit
FileCtrl
uses FileCtrl;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not DirectoryExists(’c:\temp’) then
if not CreateDir(’C:\temp’) then
raise Exception.Create(’Cannot create c:\temp’);
end;
--------------------------------------------------------
ForceDirectories 目录
---------------------------------------------------------
Unit FileCtrl
函数原型 function ForceDirectories(Dir: string): Boolean;
procedure TForm1.Button1Click(Sender: TObject);
var
Dir: string;
begin
Dir := ’C:\APPS\SALES\LOCAL’;
if DirectoryExists(Dir) then
Label1.Caption := Dir + ’ was created’
end;
--------------------------------------------------------
ExpandUNCFileName 同上(只是得到网路上的路径)
--------------------------------------------------------
Unit SysUtils
函数原型 function ExpandUNCFileName(const FileName: string):string;
ExtractFileDir 分析字串中的路径
Unit SysUtils
函数原型 function ExtractFileDir(const FileName: string): string;
说明 设S字串为 c:\windows\abc.txt
则结果为 c:\windows
**** 功能在於由任何部份传来的叁数,加以分析它的路径
范例 procedure TForm1.Button1Click(Sender: TObject);
var
S: String;
P1:String;
begin
P1:=’c:\windows\abc.txt’;
S:=ExtractFileDir(P1);
Label1.Caption:=S;
end;
S==’c:\windows’
P1:=’abc.txt’
S==’
P1:=’c:abc.txt’
S==’c:’
P1:=’c:\abc.txt’
S==’c:\’
----------------------------------------------