📄 d_note06.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>心得06</title>
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
<style type="text/css">
<!--font { font-size: 9pt ; line-height:15pt;A{text-transform: none; text-decoration: none;}-->
</style>
<style>
<!--
A:link {text-decoration: none; color: #FF8000}
A:visited {text-decoration: none; color: #FF8000}
A:active {text-decoration: none}
A:hover {text-decoration: underline; color: #FF8000}
body,table {font-size: 9pt}
H8 {font-size: 9pt ; line-height:15pt; align=center}
ourfont {font-size: 9pt ; line-height:15pt; }
ourfont1 {font-size: 9pt ; line-height:15pt; }
-->
</style>
<meta name="Microsoft Border" content="tlb, default"></head>
<body><!--msnavigation--><table border="0" cellpadding="0" cellspacing="0" width="100%"><tr><td>
<h1 align="center">心得06</h1>
<h4 align="center"><nobr>[ <a href="../">蜗牛的家</a> ]</nobr> <nobr>[ <a href="d_note00.htm">心得00</a> ]</nobr> <nobr>[ <a href="d_note01.htm">心得01</a> ]</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>[ 心得06 ]</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>99-6-26 <strong>关于SQL的一点疑问
</strong>今天在写一个数据库应用程序时,用到了一个SQL查询
select name // 从基本信息表中取姓名并要满足下面条件
from an01
where serial in ( // 姓名对应的序号在……之中
select a00 // 从培训班数据表中取出所有序号要求是
from an43
where a01=:a01 // 培训班号等于一结定值
)
结果无论我怎样改变参数a01的值,这一查询返回的结果总是第一次查询的结果。我只好换另一种方法
select name from an01 a,an43 b
where a.serial=b.a00 and b.a01=:a01
结果竟然通过了。我不知道为什么前者不成功后者成功了。你知道吗?</pre>
<pre>99-6-6 <strong>关于RXLib260
</strong>朋友建议我用一下RXLib2.6里的RXRichedit控件。我<a href="http://www.nease.net/~bozhi/down/rxlib260.zip">下载</a>了一个,一用之下,
还真的很好。RXRichEdit能支持UniCode、对象(如图片)、URL的自动显示及
单击激活功能、支持缺省为100次的UNDO、内置了查找/替换功能等等。这下用良
友的朋友们有福了! :)</pre>
<pre>看Demo时,无意中看到了个WinAbout函数,是RX在Rxshell.pas中自定义的。
在程序里用了一下:
WinAbout('Win','About');
啊哈!</pre>
<pre>99-6-3 <strong>网友提问的几个问题
</strong>l> 你好:
l> 我刚学delphi4.0不久,遇到了不少问题,现想请你指教一下:
l> 1、如何设置按回车键相当于单click?(例如在dbgrid表格中)
答:在窗体form1中放入table1,datasource1,dbgrid1,设好联连关系,使dbgrid1
中能正确显示出table1的数据。然后:
procedure TForm1.DBGrid1KeyPress(Sender: TObject;
var Key: Char);
begin
with DBGrid1 do
if Key=#13 then
DBGrid1CellClick(Columns[SelectedIndex]);
end;
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
with DBGrid1 do
showmessage(format('row=%d',[SelectedIndex]));
end;
l> 2、如何用语句调用其他控件的过程和方法?
答:注意上面的例子里的
if Key=#13 then DBGrid1CellClick(Columns[SelectedIndex]);
这就是调用了其它控件的method。
l> 3、show窗体的时候如何激活窗体上的菜单?
答:在form1上增加一个mainmenu1,设好菜单项,再设form1的menu属性为mainmenu1即可。
l> 4、初次装入列表框的时候,如何设置选定默认选项?
答:ListBox1.itemindex:=n;
(n即为默认选项的index)
l> 5、用query控件生成的临时数据表,能否当源表来重用,如用select来继续查询
等,或保存到一个新建数据表中,以备用?
答:可以保存起来。但需要在运行中动态生成数据库表。具体请见TTable.CreateTable的联机帮助。
l> 6、用delphi删除的数据表记录能否恢复删除?
不能。
l> 7、delphi怎样才能象foxpro的scatter memvar
l> 和gather
l> memvar命令组那样方便地更新数据表的整条记录?
请看TDataSet.Fields的帮助及Example
l> 8、先放入一个button控件,再放入一个panel控件,如何设置使到button归属于panel?
单击Button,按Ctrl-X;再单击panel,按ctrl-C。如果要批量转移,请看我的开发心得。</pre>
<pre>99-6-1 <strong>string、TStrings、pchar的相互转换</strong>(这里是我的个人经验)
假设有如下定义:
var
p:pchar;
s:string;
ss:tstrings;
begin
ss:=tstringlist.create; // 开始时一定不要忘记创建ss
ss.text:=s; // string --> tstrings
s:=ss.text; // tstrings --> string
p:=pchar(s); // string --> pchar
s:=p; // pchar --> string
showmessage(s); // 合法语句
showmessage(p); // 合法语句
... ...
ss.free; // 最后还要记着释放ss占用的资源
end;</pre>
<pre>99-5-31 <strong>惨痛教训一例
</strong>今天在我单位财务科,想在我编写的记帐程序中添加一点功能,先在acc.db表上建立索引。
(其实我对数据库方面的东西不算很熟,因为我更喜欢把时间花在开发些实用软件工具方面)
用Database Desktop打开acc.db,选“Restructure...”,给其中的头两个字段加上
主索引,即在右边加上“*”号。然后Save,发现显示了一个表格,大概是产生冲突的记录
列表。我没在意,就关掉了窗口。正式运行程序时,发现原来记的帐少了许多(存放在acc.db
中),几千条记录只剩下300条了……想啊想,终于想起来了:我建立的索引是唯一索引,
Database Desktop自动把重复的记录剔了出来,当时显示的那个表就是!我应该马上保存
才对!这一下,就要辛苦操作人员补记上次备份以来的帐了。真不好意思。</pre>
<pre>99-5-30 <strong>使Panel上的所有组件无效/有效
</strong>在开发过程中,免不了时常要使整个Panel上的组件同时无效,然后在适当时机同时有效。
这里有个好办法:
MyPanel.enabled:=false;
此后,从属于MyPanel上的所有组件就都被禁止了。</pre>
<pre>99-5-20 <strong>制作出类似资源管理器的工具条
</strong>要达到这个目的,需要先掌握TCoolBar的用法。这个组件用起来很特别,需要一点技巧,
要多试几次才能得心应手。</pre>
<pre>先在CoolBar上放一个ToolBar,在它上面放置模仿菜单项的按钮,具体要去看一下
Demos\Docking\Main.pas的示例。有一点值得一提:记住把ToolButton的Grouped
设为True,否则,嘿嘿!你的“菜单”会很难用!</pre>
<pre>以上建立的“菜单”不同于普通应用程序中常见的那种一直位于屏幕最顶上的主菜单,
而是象资源管理器里一样,能够被鼠标拉着动。</pre>
<pre>然后还要建立快捷按钮。方法同样还是在CoolBar上放置ToolBar,具体步骤我就不再
仔细描写了。</pre>
<pre>99-5-18 <strong>几个必备function
</strong>function Confirm(prompt:string):boolean;
begin
result:=MessageBox(application.handle,
pchar(prompt),
'确认',mb_ICONQuestion+mb_YesNo)=mrYes;
end;</pre>
<pre>procedure ShowMsg(Msg:string);
begin
MessageBox(application.handle,
pchar(Msg),
pchar(Application.title),
mb_ICONInformation);
end;</pre>
<pre>99-5-18 <strong>TRichEdit快速插入字符串
</strong>请注意看下面这段程序:<strong>
</strong>procedure TMainForm.InsertSomethingToMemo(s:string);
var
c:integer;
begin
with ContentMemo do
begin
c:=SelStart;
SelText:=s; // 关键
SelStart:=c+length(s);
SelLength:=0;
Modified:=true;
end;
end;
其中的SelText:=s就很容易地做到了。如果你没有看到我的程序的话,能不能很快想
到这个办法呢?</pre>
<pre>99-5-10 <strong>RXLib的AppEvents组件
</strong>在Delphi中,有一个重要的类TApplication,它被预定义成一个系统级的全局变量:
Application。Application有许多属性、方法和事件,合理地管理和定制它,就能
极其灵活地控制应用程序的各个方面。RXLib提供了这个TAppEvents控件,使我们可
以在设计期间就能象对其它VCL组件一样直观地对它的各项属性赋值,还可以直接编写
各个事件处理过程,哇,太方便了。(注:RXLIB2.5是一个优秀的免费Delphi控件集,
带源码,在Delphi小站上有提供。)</pre>
<pre>有空我要写一个RXLib主要控件简介。</pre>
<pre>99-5-1 <strong>良友秘笈:HZ->GB码的转换示例!</strong>
function HZtoGB(S: string): string;
// 我写的自定义函数,从Str的第Start个字符处
// ..开始找SubStr,找到返回位置(相对于Str)
// ..找不到返回0
function PosX(SubStr,Str:string;Start:integer):integer;
begin
result:=Start+pos(Substr,copy(s,Start,MaxInt))-1;
if result<Start then result:=0;
end;
function InternalHZtoGB(s:string):string;
var
i,len:integer;
begin
len:=length(s);
SetLength(result,len);
for i:=1 to len do
result[i]:=char(ord(s[i]) or 128);
if (len mod 2)=1 then
result[len]:=char(ord(s[len]) and 127);
end;
var
LIdx,RIdx:integer;
begin
result:='';
LIdx:=pos('~{',s);
RIdx:=1;
While LIdx>0 do
begin
result:=result+copy(s,RIdx,LIdx-RIdx);
RIdx:=PosX('~}',s,LIdx);
if RIdx=0 then
begin
result:=result+copy(s,LIdx,MaxInt);
break;
end;
result:=result+InternalHZtoGB(copy(s,LIdx+2,RIdx-LIdx-2));
inc(RIdx,2);
LIdx:=PosX('~{',s,RIdx);
end;
result:=result+copy(s,RIdx,MaxInt);
end;
</pre>
<p>99-3-23 1:00:00<br>
在<strong>设计Menu时,常用的ShortCut</strong>可从下拉菜单中选取。但我发现可选的ShortCut有些不在列表中,如ESC,Ctrl-Shift-A等。我试着在ShortCut项的右边输入:ESC,竟然成功了。再试Ctrl-Shift-A,这回Delphi自动把它变为Shift-Ctrl-A,呵呵,原来如此。</p>
<p>99-3-20<br>
不知你有没有注意到,<strong>Delphi4所带的Quick Report有些不大好用</strong>。比如:在ColumnHeaderBand1上放几个QRLabel,结果在预显示和打印时,第一页上竟然没有这几个QRLabel!从第二页起才开始出现。在Delphi3的QRLabel里就没有这个Bug。没办法,只好采取一个折衷的措施:把所有ColumnHeaderBand1上的内容移到PageHeaderBand1上去。</p>
<p>什么!不会移?看好了:<br>
·按住ctrl键,拖动鼠标,尽可能多地选中ColumnHeaderBand1上的控件<br>
·按下Ctrl-X(剪切),——没有了;<br>
·点一下PageHeaderBand1,按下Ctrl-V,所有选中的控件都上来了。<br>
·调整PageHeaderBand1的大小及刚才粘贴上的控件的位置。<br>
重复刚才的操作,直到完成。</p>
<p>99-3-4 20:55:28<br>
<strong>我对fillchar的初步认识</strong><br>
var<br>
p:pchar;<br>
begin<br>
getmem(p,100);<br>
fillchar(p^,99,'c'); // fillchar(p,99,'c')就是绝对错误的!!!<br>
p[99]:=#0;<br>
...</p>
<p>99-3-4 20:55:33<br>
<strong>对fillchar的再认识</strong>(下面这个试验通过了。)<br>
procedure TMainform.Button1Click(Sender: TObject);<br>
var<br>
p:pchar;<br>
s:string;<br>
begin<br>
getmem(p,100);<br>
fillchar(p^,99,'c');<br>
p[99]:=#0;<br>
s:=p;<br>
showmessage(string(p)+' -- '+s); // 'cccc... -- cccc...'<br>
freemem(p);<br>
showmessage(string(p)+' -- '+s); // '@$#%... -- cccc...'<br>
end;</p>
<p>99-3-4 20:58:37<br>
(Delphi 4)<strong>Anchors属性</strong>设为 akRight & akBottom时,元件会伴随着容器的右下角做相应移动。<br>
更深入一步:当改变Align属性时,Anchors的属性值也随之变化。注意观察就会看出其中的规律。无论如何,Align控制更简易,而用Anchors控制更高级,更灵活。熟练使用Anchors控制元件在窗口上的位置,可以省去很多编程工作。</p>
<p>99-3-5<br>
<strong>Delphi 4中TTreeView的bug</strong>:假设我们要将某个结点treenode移动到另一结点AnItem上并做为AnItem的child,按照文档说明,只需这样做<br>
TreeNode.moveto(AnItem,nrAddChild);<br>
但实际上,在Delphi 4中,假如anode原来没有child的话,这条语句将不做任何事情。折衷的办法是<br>
TempNode:=TopicTV.items.AddChild(AnItem,'');<br>
TreeNode.MoveTo(TempNode, naInsert);<br>
TempNode.free;<br>
在Tipexplr程序的源码中,关于实现同样操作,它指出,Delphi的TTreeView有bug,并提供了自己的解决方法(见下),但这只能在Delphi
3中通过,在Delphi 4中,只能用我的上面的方法。<br>
AttachMode := naAddChild; { Add tip as a child of category }<br>
<br>
{ Note: Adding the temporary node is a work around to a bug }<br>
{ that exists in the TreeView component when moving a }<br>
{ node to a another node that doesn't have any children }<br>
<br>
TempNode := TvwTips.Items.AddChild( TvwTips.DropTarget,'Temp' );<br>
try<br>
{ Move the node in the tree view }<br>
TvwTips.Selected.MoveTo( TvwTips.DropTarget, AttachMode );<br>
<br>
{ Now need to update the category of tip in the database }<br>
TblTips.DisableControls;<br>
try<br>
TblTips.Edit;<br>
TblTips[ 'Category' ] := TvwTips.DropTarget.Text;<br>
TblTips.Post;<br>
finally<br>
TblTips.EnableControls;<br>
end;<br>
<br>
finally<br>
TempNode.Free; { Don't forget to release the temp node }<br>
end;<br>
<!--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 + -