📄 d_note01.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>心得01</title>
<meta NAME="Author" CONTENT="安富国">
<meta NAME="GENERATOR" CONTENT="Microsoft FrontPage 3.0">
<meta name="Microsoft Border" content="tlb, default"></head>
<body><!--msnavigation--><table border="0" cellpadding="0" cellspacing="0" width="100%"><tr><td>
<h1 align="center">心得01</h1>
<h4 align="center"><nobr>[ <a href="d_note00.htm">心得00</a> ]</nobr> <nobr>[ 心得01 ]</nobr> <nobr>[ <a href="d_note02.htm">心得02</a> ]</nobr> <nobr>[ <a href="d_note03.htm">心得03</a> ]</nobr> <nobr>[ <a href="d_note04.htm">心得04</a> ]</nobr> <nobr>[ <a href="d_note05.htm">心得05</a> ]</nobr> <nobr>[ <a href="d_note06.htm">心得06</a> ]</nobr> <nobr>[ <a href="d_question.htm">疑难问题</a> ]</nobr></h4>
</td></tr><!--msnavigation--></table><!--msnavigation--><table border="0" cellpadding="0" cellspacing="0" width="100%"><tr><td valign="top" width="1%">
<p></p>
</td><td valign="top" width="24"></td><!--msnavigation--><td valign="top">
<pre>
<i>98-6-22 11:08</i>
翻出数月前下载的一个<b>Delphi增强元件库rxlib.zip</b>,照着其中的说明文件
安装到我的Delphi3下,忽然有种感觉:要是以开发Delphi元件为荣的人见到
rxlib.zip一定会有"既生瑜,何生亮"的感觉.这个元件库做得实在是太好了.
<i>98-6-19 9:26</i>
<b>奇怪的I/O error</b> -- 我在开发过程中发现下面这两条语句
assignfile(fDesc,CDDatadir+describefile);
reset(fDesc);
每当我第一次运行到这里时,总会出现 I/O Error 183 的错误.
最后我想这也有可能是没有清除 ioresult 的原因.在两句之间加入
if ioresult<>0
then;
oooook! 可以了.
<i>98-6-18 11:40</i>
<b>值得注意的I/O error</b>
AssignFile(F, fname);
Rewrite(F);
当文件 F 经 Reset(F)打开的情况下, Rewrite(F)会引发一个异常: I/O error 32
反之,经 Rewrite(F)打开, Reset(F)也会引发同一个异常.
Reset(F)两次,closefile(F),再Rewrite(F),或反之,也会引发同样异常.
<i>98-6-17 1:40</i>
<b>关于FileListBox的一个无法避免的陷阱</b>
Delphi叫我既爱且恨。我做了个程序,是扫描光盘目录的。用到了FileListBox元件。
每当我转到光盘上的某个特定文件夹后,换上另一张光盘,再次扫描,FileListBox就
会报错:File not found. 为了这个错误,我调试了整整两天!开始以为是自己程序
中有逻辑错误,可无论怎么改,每次换盘后,一更新FileListBox.directory,出错信
息依旧。最后我想了个最直接的方法:只放一个FileListBox和一个Edit元件,同样的
换盘顺序,哈!同样的错误信息再次出现。看看Delphi的源程序吧:
-- I:\Program Files\Borland\Delphi 3\Source\VCL\filectrl.pas中:
procedure TFileListBox.SetDirectory(const NewDirectory: string);
begin
if AnsiCompareFileName(NewDirectory, FDirectory) <> 0 then
begin
{ go to old directory first, in case not complete pathname
and curdir changed - probably not necessary }
ChDir(FDirectory); // 哼!就是这儿,害得我好惨。
ChDir(NewDirectory); { exception raised if invalid dir }
GetDir(0, FDirectory); { store correct directory name }
ReadFileNames;
end;
end;
唉,连Delphi先生都说:“可能不需要”(probably not necessary)。
而实际上,我在修改了这里之后,仍然不对. 我又发现,在filectrl.pas中,有好几处这样
的地方需要修改. 最后,我只得放弃用FileListBox,改用ListBox了. 唉!
<i>98-6-17 1:12</i>
<b>ExtractAssociatedIcon()和ExtractIcon()</b> 可从指定文件中分离出其icon
或其相关程序的icon.
// Delphi 3
// uses ..., ShellAPI;
procedure TForm1.Button1Click(Sender: TObject);
var
FileName: AnsiString;
begin
FileName := 'd:\temp\Project1.exe';
Image1.Picture.Icon.Handle :=
ExtractIcon(Hinstance, pchar(FileName), 0);
end;
<i>98-6-17 1:01</i>
<b>Lloyd's help file (ldelphi.zip)</b> 钱达智兄推荐的技术文件。
<b>TrayIcon.zip</b> 同样是达智兄推荐的一个协助将您的程式放到开始功能列的右下角的元件。
<i>98-6-13 2:36</i>
<b>string和pchar的相互转换:</b>
string --> pchar: pchar(str:string);
pchar --> string: strpas(p:pchar);
<i>98-6-12 18:02</i>
<b>关于IOResult</b>
唉!虽然我喜欢Delphi,可也不希望有一个个的bug出现!
procedure TForm1.FormCreate(Sender: TObject);
begin
{$i-}
chdir('dsafadsf');
chdir('.');
{$i+}
showmessage(inttohex(ioresult,4));
showmessage(inttohex(ioresult,4));
end;
请看这个过程:自己作一下,你会发现,两个Showmessage的结果竟然不一样!
--= 98-6-18 11:03 =--
Sorry, 我错怪Delphi了. 事实上, 在Delphi中, 当设为{$i-}之后, 如果
发生了I/O错误, 一定要调用IOResult来清除这一错误代码.(见联机帮助)
(爱之深,恨之切嘛. xixi)
<i>98-6-10 14:53</i>
<b>给数组直接赋值的方法:</b>
ArrayTest: array[1..2, 1..2] of integer =
((1, 2), (3, 4));
<b>变量命名法:</b>(这种前置小写变量类型的做法挺好)
iRecord: integer;
recRead: TTest;
-----------------<b>《DELPHI新闻组学习笔记》</b>---------------
这类字串函数(像是PadR,PadL)自己练习写写看其实挺有趣的;如果急着要用,类似这样子的字串处
理函数在网络上不少,如Delphi 2.0 深度历险就有个叫做 XProc 的档案,里头就有很多。
幸好我这里有 cj.sor..., 以后有这种问题时,请告诉大家 cj.sor . boshiamy.sor. phone.sor 可以
从哪里取得,这样,有心帮忙的朋友好帮忙测试。
-----------------《DELPHI新闻组学习笔记》---------------
(cj.sor是什么?)
<i>98-6-9 22:55</i>
作了一个<b>鼠标拖放</b>的编程。发现有一个地方有点容易弄错,那就是在
OnDragOver事件中,一定要显式地指定Accept的值。
procedure TMainForm.DescListBoxDragOver(Sender, Source: TObject; X,
Y: Integer; State: TDragState; var Accept: Boolean);
begin
if (Source=FileListBox) and (fileexists(FileListBox.FileName))
then accept:=true;
end;
这是错的。只有在then子句后加入
else accept:=false;
才能得到正确的结果。当然,还有一个更简单的写法,只要一行:
accept:=(Source=FileListBox) and (fileexists(FileListBox.FileName));
<i>98-6-8 22:29</i>
今天看到了<b>《DELPHI新闻组学习笔记》</b>,不错,现摘抄一例:
11 How To Hide TaskBar Of Win95? <b>怎样隐藏Win95 的任务栏? </b>
回答
First call the Windows API function FindWindow() to retrieve
the handle to the TaskBar Window, then call the Windows API
function ShowWindow() passing the predefined constant SW_HIDE.
Example:
procedure TForm1.Button1Click(Sender: TObject);
var
hTaskBar : THandle;
begin
hTaskbar := FindWindow('Shell_TrayWnd', Nil);
ShowWindow(hTaskBar, SW_HIDE);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
hTaskBar : THandle;
begin
hTaskbar := FindWindow('Shell_TrayWnd', Nil);
ShowWindow(hTaskBar, SW_SHOWNORMAL);
end;
(归根到底,还是使用了Windows API。)
<b>关于Win95快捷方式的API函数:IShellLink</b>
详情可从Win32 Programmer's Reference中查到。值得一提的是:
Resolve 在必要时候对IShellLink进行刷新
GetWorkingDirectory 取得IShellLink的工作目录
<i>98-6-8 3:19</i>
<b>我发现了Delphi的一个小的问题:</b>
在Delphi的原班函数和 Win32 Api 中,各有一个函数为closefind。当uses子句中
包含windows时,closefind便自动使用Win32 Api的说明。如
FindClose(SearchRec);
只好改为
FindClose(SearchRec.findhandle);
不知有无更好的方法。:(
--= 98-8-8 =--
找到了! 用 Sysutils.FindClose(SearchRec);
<b>函数findfirst和findnext的通用例程</b>
Found := FindFirst(Path, Attr, SearchRec);
while Found = 0 do
begin
ProcessSearchRec(SearchRec);
Found := FindNext(SearchRec);
end;
FindClose(SearchRec);
<i>98-6-8 1:31</i>
exit用在主程序中会中止程序;用在过程中则会单纯地退出这个过程。
这本是个简单的常识,我却到现在才会......
<i>98-6-7 23:31</i>
<b>保留字Initialization和finalization</b>
在一个Form的源代码的结束行的标志"end."前,可以加上如下两个保留字
initialization
{ 在这里你可以对数据进行初始化 }
finalization
{ 这里你可以做一些善后工作,如释放内存 }
end.
<i>98-6-6 1:55</i>
<b>GetVolumeInformation函数及其帮助文件的小错误</b>
函数GetVolumeInformation可以取得指定盘符的文件系统类型和其它一些重要参数
BOOL GetVolumeInformation(
LPCTSTR lpRootPathName, // address of root directory of the file system
LPTSTR lpVolumeNameBuffer, // address of name of the volume
DWORD nVolumeNameSize, // length of lpVolumeNameBuffer
LPDWORD lpVolumeSerialNumber, // address of volume serial number
LPDWORD lpMaximumComponentLength, // address of system's maximum filename length
LPDWORD lpFileSystemFlags, // address of file system flags
LPTSTR lpFileSystemNameBuffer, // address of name of file system
DWORD nFileSystemNameSize // length of lpFileSystemNameBuffer
);
这是在Win32API的Help文件中的说明,可惜有些错误,那就是最后两个LPDWORD,应为DWORD才对。
<i>98-6-5 14:38</i>
<b>demos/doc/filmanex/fmxutils.pas有一处bug</b>
<i>98-5-31 3:07</i>.
看了<b>demos/teechart</b>中的例程,哇!功能太全太多了。
chat* lov teechart
号外号外,文安小生和teechart相爱了!
<i>98.5.29</i>
<b>我找了许久,并在无意中发现的--有关String类型的另两个函数/过程</b>
procedure SetLength(var S: string; NewLength: Integer);
function Length(S: string): Integer;
//Length returns the number of characters used in a string.
chat* ah
<i>98.5.25</i>
<b>string的相关过程和函数(省得以后到处找:)</b>
The SysUtils unit provides a number of null-terminated string handling functions.
The following table gives a brief description of each of these functions.
-------- -----------
Function Description
-------- -----------
StrAlloc Allocates a character buffer of a given size on the heap.
StrBufSize Returns the size of a character buffer allocated using StrAlloc or StrNew.
StrCat Concatenates two strings.
StrComp Compares two strings.
StrCopy Copies a string.
StrDispose Disposes a character buffer allocated using StrAlloc or StrNew.
StrECopy Copies a string and returns a pointer to the end of the string.
StrEnd Returns a pointer to the end of a string.
StrFmt Formats one or more values into a string.
StrIComp Compares two strings without case sensitivity.
StrLCat Concatenates two strings with a given maximum length of the resulting string.
StrLComp Compares two strings for a given maximum length.
StrLCopy Copies a string up to a given maximum length.
StrLen Returns the length of a string.
StrLFmt Formats one or more values into a string with a given maximum length.
StrLIComp Compares two strings for a given maximum length without case sensitivity.
StrLower Converts a string to lowercase.
StrMove Moves a block of characters from one string to another.
StrNew Allocates a string on the heap.
StrPCopy Copies a Pascal string to a null-terminated string.
StrPLCopy Copies a Pascal string to a null-terminated string with a given maximum length.
StrPos Returns a pointer to the first occurrence of a given substring within a string.
StrRScan Returns a pointer to the last occurrence of a given character within a string.
StrScan Returns a pointer to the first occurrence of a given character within a string.
StrUpper Converts a string to uppercase.
<b>命令行参数的使用</b>
Delphi提供了访问命令行参数的方便的方式,那就是使用
ParamStr和ParamCount函数。其中ParamStr(0)返回的是当
前程序名,如C:\TEST\MYPROG.EXE,ParamStr(1)返回第一
个参数,以此类推;ParamCount则是参数个数。示例如下
var
I: Word;
Y: Integer;
begin
Y := 10;
for I := 1 to ParamCount do begin
Canvas.TextOut(5, Y, ParamStr(I));
Y := Y + Canvas.TextHeight(ParamStr(I)) + 5;
end;
end;
<b>修改系统时间时应注意的问题</b>
一开始,我使用GetSystemTime和SetSystemTime,但发现结果不对,
经仔细检查才知道,这中间的误差是8个小时,正好是中国的时区数。
改用GetLocalTime和SetLocalTime后,一切正常。
</pre>
<!--msnavigation--></td></tr><!--msnavigation--></table><!--msnavigation--><table border="0" cellpadding="0" cellspacing="0" width="100%"><tr><td>
<p align="center"> </p>
</td></tr><!--msnavigation--></table></body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -