[delphi]技巧集合

  • A+
所属分类:[开发技巧]

INI文件的操作要点
(1)在interface关键字后的uses子句中加入
uses ...,inifiles;
(2)设置变量:var inifile:=TIniFile;
(3)使用前,一定要先做:
inifile:=TIniFile.Create(inifilename);
我在这里绕了个弯子,写成
inifile.Create(inifilename);

TShiftState用来检测CTRL,ALT,Shift,以及鼠标按键的状态,
常常用在键盘或鼠标的事件处理程序之中。

DCU文件(编译的库单元)的重用
(1)在interface里的uses子句中引用。如Windows,Dialogs,
等等,要求被引用的DCU一定要放在Delphi 3\Lib子目录中。
(2)在implementation里的uses子句中引用。如果是自行编写的
DCU文件,应采用这一方式,并将被引用的DCU文件放入当前
工程所在的子目录中。
executefile函数(在FmxUtils.DCU中定义)不能用在FormCreate
事件中。真奇怪......

内置的版本号控制功能
在Project Options中的VersionInfo项里,有版本信息的定制,
包括一个有趣的版本号自动增加功能(Auto-increment build
number),即每Build一次,版本号中的Build Number加1。选中
Include version information in project,编译,用资源管
理器里找到生成的.exe文件,点右键,查看“属性”一项,就
会看到在属性中多了一页“版本”,里面就是你刚才输入的各
项内容。

定制Speedbar
右键点击左上角的加速键条(speedbar),选中Properties,
在列表框中找到你想要加入speedbar的命令按钮,将它拖到
speedbar上的合适位置即可。如果speedbar上没有多余的空间
来容纳新的按钮,可把鼠标在speedbar右框处变为双向箭头的
形状,向右拖动一段距离,就可腾出空间。如想删除speedbar
上的某个按钮,可简单地把它拖出speedbar的范围,就能删除。

计算出的字段
在写一个程序时,我要在DBGrid中显示出一个memo的部分信息,当我把那个
memo字段放进去后,运行时只能显示出“(memo)”字样。从书上找到计算字
段的用法后,我在TTable中增加一个计算字段MemoHeader,宽度为40,在此
TTable的OnCalcFields事件中输入:
with MyTable do
FieldByName('memoheader').asstring:=FieldByName('memo').asstring;
在DBGrid中放入MemoHeader,运行,OK!

字段编辑器
解决了上面的问题后,我继续学习字段编辑器的作用。原来,DELPHI通过字
段编辑器,近乎完美地实现了数据库的字段级的控制,这包括:
1)字段在DBGrid中标题、宽度、能否可见;
2)字段的显示格式和编辑时输入的过滤条件;
3)字段是否只读;
4)字段的类型:数据字段/计算字段/查询字段/内部计算字段;
5)字段的显示/赋值/修改等事件的定制。

设计Form时的快捷键
Del 删除所选组件
Esc 选择当前组件的容器(通常是Panel,Group或Form)
F11 在Form或Unit和对象检查器之间切换
F12 在Form和代码编辑器间切换
Ctrl-F12 显示“查看Unit”对话框
Shift-F12 显示“查看Form”对话框
TAB 下一个组件
Shift-TAB 上一个组件
方向键 选中此方向上最近的组件
Ctrl-方向键 将所选组件移动一个点
Shift-方向键 将所选组件改变一个点的大小
Ctrl-Shift-方向键 将所选组件移动一个格
Shift-click 按住Shift键再用鼠标点击组件,可以选择多个组件。
--= 下面这条是我摸索出来的 =--
Ctrl-drag 按住Ctrl键在一个容器组件(如Panel,QReport,Groupbox等)
里拖动鼠标,可强制选择鼠标拖过的矩形框中的所有属于此容
器的可视组件但不包括该容器组件。

使用QReport的若干经验
1)QuickRep1.DataSet:=query1
不然无输出结果
2)从qrpt2man.doc中查知,格式化输出结果的方法是:
在QRDBText.Mask中设为.00;0,将使输出带两位小数。
3)设置Group时,先加入一个QGroup,再加入一个QRBand,将QGroup的
FooterBand设为刚才的QRBand,就可将其联系起来。
4)在Group中打印的合计数,其ResetAfterPrint设为True,可实现分组合

format('%*.*f',[8,2,123.456]); //等价于format('%*8.2f',[123.456])
format('%d %d %0:d %d'[10,20]);

播放一个wav文件
use mmsystem;
SndPlaySound('hello.wav',SND_FILENAME or SND_SYNC)

使你的form适应不同的显示分辨率
假设你在800*600的分辨率下设计的form,第一步:
inplementation
const
ScreenWidth: LongInt = 800; {I designed my form in 800x600 mode.}
ScreenHeight: LongInt = 600;

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
scaled := true;
if (screen.width <> ScreenWidth) then
begin
height := longint(height) * longint(screen.height) div ScreenHeight;
width := longint(width) * longint(screen.width) div ScreenWidth;
scaleBy(screen.width, ScreenWidth);
end;
end;

下一步,要让每个子控制的字体改变到合适的大小:
type
TFooClass = class(TControl); { needed to get at protected }
{ font property }

var
i: integer;
begin
for i := ControlCount - 1 downto 0 do
TFooClass(Controls[i]).Font.Size :=
(NewFormWidth div OldFormWidth) *
TFooClass(Controls[i]).Font.Size;
end;

用raise引发一个错误处理例程
示例:先给出下面的定义
type EPasswordInvalid=class(Exception);
这样你就可以随时引发一个"password invalid"的例外:
if Password<>CorrectPassword then
raise EPasswordInvalid.Create('Increect Password entered');
运行后,出现信息框
Project Project1.exe raise exception class EPasswordInvalid
with message 'Incorrect Password entered'. Process stopped.
Use step or run to continue.
再按Run按钮,出现一个信息框:
Incorrect Password entered.

从DEMO例程中学到的若干小技巧
在demo\internet\http\webbrows\main.pas中,
procedure TForm1.DocumentSourceClick(Sender:Tobject);
begin
with DocSourceForm do
begin
show; // 显示HTML源码的FORM
Memo1.lines.clear; // 清空memo1中内容
Memo1.lines.add(HTML1.SourceText); // 植入源码
Memo1.SelStart:=0 // ***
SendMessage(Memo1.Handle, // Memo1的窗口句柄
EM_ScrollCaret //将Edit Control中的caret光标滚动到视野中
0,0 //这两个参数暂不使用
end;
end;
(此SendMessage系一WinAPI调用,给一个或一组窗口发送消息,直到
相应窗口处理此消息后才有返回值。相似的另一函数为PostMessage,
它将消息放入消息队列中后立即返回。)
*** 清空当前选择并将光标移动到指定字符(0代表第一个字符)。如同时
设memo1.sellength为一非0值,可选择一段文本。

奇怪的I/O error -- 我在开发过程中发现下面这两条语句
assignfile(fDesc,CDDatadir+describefile);
reset(fDesc);
每当我第一次运行到这里时,总会出现 I/O Error 183 的错误.
最后我想这也有可能是没有清除 ioresult 的原因.在两句之间加入
if ioresult<>0
then;
oooook! 可以了.

值得注意的I/O error
AssignFile(F, fname);
Rewrite(F);
当文件 F 经 Reset(F)打开的情况下, Rewrite(F)会引发一个异常: I/O error 32
反之,经 Rewrite(F)打开, Reset(F)也会引发同一个异常.
Reset(F)两次,closefile(F),再Rewrite(F),或反之,也会引发同样异常.

string和pchar的相互转换:
string --> pchar: pchar(s
tr:string);
pchar --> string: strpas(p:pchar);

Delphi代码中定义数据库
procedure tform1.create_tbl;
var tbl:ttable;
begin
tbl:=ttable.create(self); // 如没有声明中的"tform1.",Delphi不认这个self
with tbl do
begin
datebasename:=;dbdemos';
tablename:='my_tbl';
with fielddefs do
begin
clear;
add('No',ftInteger,0,false);
add('Name',ftString,0,false);
...
end;
with indexdefs do
begin
clear;
add('primary','no',[ixPrimary,ixUnique]);
...
end;
CreateTable;
end;
end;

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;

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

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin
广告也精彩
avatar
广告也精彩

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: