Delphi----心得06

99-6-26  关于SQL的一点疑问
今天在写一个数据库应用程序时,用到了一个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
结果竟然通过了。我不知道为什么前者不成功后者成功了。你知道吗?
99-6-6  关于RXLib260
朋友建议我用一下RXLib2.6里的RXRichedit控件。我下载了一个,一用之下,
还真的很好。RXRichEdit能支持UniCode、对象(如图片)、URL的自动显示及
单击激活功能、支持缺省为100次的UNDO、内置了查找/替换功能等等。这下用良
友的朋友们有福了! :)
看Demo时,无意中看到了个WinAbout函数,是RX在Rxshell.pas中自定义的。
在程序里用了一下:
    WinAbout('Win','About');
啊哈!
99-6-3  网友提问的几个问题
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。如果要批量转移,请看我的开发心得。
99-6-1  string、TStrings、pchar的相互转换(这里是我的个人经验)
假设有如下定义:
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;
99-5-31 惨痛教训一例
今天在我单位财务科,想在我编写的记帐程序中添加一点功能,先在acc.db表上建立索引。
(其实我对数据库方面的东西不算很熟,因为我更喜欢把时间花在开发些实用软件工具方面)
用Database Desktop打开acc.db,选“Restructure...”,给其中的头两个字段加上
主索引,即在右边加上“*”号。然后Save,发现显示了一个表格,大概是产生冲突的记录
列表。我没在意,就关掉了窗口。正式运行程序时,发现原来记的帐少了许多(存放在acc.db
中),几千条记录只剩下300条了……想啊想,终于想起来了:我建立的索引是唯一索引,
Database Desktop自动把重复的记录剔了出来,当时显示的那个表就是!我应该马上保存
才对!这一下,就要辛苦操作人员补记上次备份以来的帐了。真不好意思。
99-5-30  使Panel上的所有组件无效/有效
在开发过程中,免不了时常要使整个Panel上的组件同时无效,然后在适当时机同时有效。
这里有个好办法:
    MyPanel.enabled:=false;
此后,从属于MyPanel上的所有组件就都被禁止了。
99-5-20  制作出类似资源管理器的工具条
要达到这个目的,需要先掌握TCoolBar的用法。这个组件用起来很特别,需要一点技巧,
要多试几次才能得心应手。
先在CoolBar上放一个ToolBar,在它上面放置模仿菜单项的按钮,具体要去看一下
Demos/Docking/Main.pas的示例。有一点值得一提:记住把ToolButton的Grouped
设为True,否则,嘿嘿!你的“菜单”会很难用!
以上建立的“菜单”不同于普通应用程序中常见的那种一直位于屏幕最顶上的主菜单,
而是象资源管理器里一样,能够被鼠标拉着动。
然后还要建立快捷按钮。方法同样还是在CoolBar上放置ToolBar,具体步骤我就不再
仔细描写了。
99-5-18  几个必备function
function Confirm(prompt:string):boolean;
begin
  result:=MessageBox(application.handle,
                     pchar(prompt),
                     '确认',mb_ICONQuestion+mb_YesNo)=mrYes;
end;
procedure ShowMsg(Msg:string);
begin
  MessageBox(application.handle,
             pchar(Msg),
             pchar(Application.title),
             mb_ICONInformation);
end;
99-5-18  TRichEdit快速插入字符串
请注意看下面这段程序:
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就很容易地做到了。如果你没有看到我的程序的话,能不能很快想
到这个办法呢?
99-5-10  RXLib的AppEvents组件
在Delphi中,有一个重要的类TApplication,它被预定义成一个系统级的全局变量:
Application。Application有许多属性、方法和事件,合理地管理和定制它,就能
极其灵活地控制应用程序的各个方面。RXLib提供了这个TAppEvents控件,使我们可
以在设计期间就能象对其它VCL组件一样直观地对它的各项属性赋值,还可以直接编写
各个事件处理过程,哇,太方便了。(注:RXLIB2.5是一个优秀的免费Delphi控件集,
带源码,在Delphi小站上有提供。)
有空我要写一个RXLib主要控件简介。
99-5-1   良友秘笈:HZ->GB码的转换示例!
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;

99-3-23 1:00:00
设计Menu时,常用的ShortCut可从下拉菜单中选取。但我发现可选的ShortCut有些不在列表中,如ESC,Ctrl-Shift-A等。我试着在ShortCut项的右边输入:ESC,竟然成功了。再试Ctrl-Shift-A,这回Delphi自动把它变为Shift-Ctrl-A,呵呵,原来如此。

99-3-20
不知你有没有注意到,Delphi4所带的Quick Report有些不大好用。比如:在ColumnHeaderBand1上放几个QRLabel,结果在预显示和打印时,第一页上竟然没有这几个QRLabel!从第二页起才开始出现。在Delphi3的QRLabel里就没有这个Bug。没办法,只好采取一个折衷的措施:把所有ColumnHeaderBand1上的内容移到PageHeaderBand1上去。

什么!不会移?看好了:
·按住ctrl键,拖动鼠标,尽可能多地选中ColumnHeaderBand1上的控件
·按下Ctrl-X(剪切),——没有了;
·点一下PageHeaderBand1,按下Ctrl-V,所有选中的控件都上来了。
·调整PageHeaderBand1的大小及刚才粘贴上的控件的位置。
重复刚才的操作,直到完成。

99-3-4 20:55:28
我对fillchar的初步认识
var
  p:pchar;
begin
  getmem(p,100);
  fillchar(p^,99,'c'); // fillchar(p,99,'c')就是绝对错误的!!!
  p[99]:=#0;
  ...

99-3-4 20:55:33
对fillchar的再认识(下面这个试验通过了。)
procedure TMainform.Button1Click(Sender: TObject);
var
p:pchar;
s:string;
begin
getmem(p,100);
fillchar(p^,99,'c');
p[99]:=#0;
s:=p;
showmessage(string(p)+' -- '+s); // 'cccc... -- cccc...'
freemem(p);
showmessage(string(p)+' -- '+s); // '@$#%... -- cccc...'
end;

99-3-4 20:58:37
(Delphi 4)Anchors属性设为 akRight & akBottom时,元件会伴随着容器的右下角做相应移动。
更深入一步:当改变Align属性时,Anchors的属性值也随之变化。注意观察就会看出其中的规律。无论如何,Align控制更简易,而用Anchors控制更高级,更灵活。熟练使用Anchors控制元件在窗口上的位置,可以省去很多编程工作。

99-3-5
Delphi 4中TTreeView的bug:假设我们要将某个结点treenode移动到另一结点AnItem上并做为AnItem的child,按照文档说明,只需这样做
  TreeNode.moveto(AnItem,nrAddChild);
但实际上,在Delphi 4中,假如anode原来没有child的话,这条语句将不做任何事情。折衷的办法是
  TempNode:=TopicTV.items.AddChild(AnItem,'');
  TreeNode.MoveTo(TempNode, naInsert);
  TempNode.free;
在Tipexplr程序的源码中,关于实现同样操作,它指出,Delphi的TTreeView有bug,并提供了自己的解决方法(见下),但这只能在Delphi 3中通过,在Delphi 4中,只能用我的上面的方法。
AttachMode := naAddChild; { Add tip as a child of category }

{ Note: Adding the temporary node is a work around to a bug }
{ that exists in the TreeView component when moving a }
{ node to a another node that doesn't have any children }

TempNode := TvwTips.Items.AddChild( TvwTips.DropTarget,'Temp' );
try
  { Move the node in the tree view }
  TvwTips.Selected.MoveTo( TvwTips.DropTarget, AttachMode );

  { Now need to update the category of tip in the database }
  TblTips.DisableControls;
  try
    TblTips.Edit;
    TblTips[ 'Category' ] := TvwTips.DropTarget.Text;
    TblTips.Post;
  finally
    TblTips.EnableControls;
  end;

finally
  TempNode.Free; { Don't forget to release the temp node }
end;

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值