標題:
delphi 技巧合輯
[打印本頁]
作者:
segaa
時間:
2010-3-10 04:40 PM
標題:
delphi 技巧合輯
INI文件的操作要点
3 f# O: E+ \! {9 W/ ^, ]# [2 g
(1)在interface关键字后的uses子句中加入
& A6 ~: w1 G- v- |7 m- X9 N4 }
uses …,inifiles;
8 c2 b" a4 N( L" T+ W3 q4 Q I
(2)设置变量:var inifile:=TIniFile;
# F2 W+ |0 N( t. n' D
(3)使用前,一定要先做:
% d, t7 a; Q j' D( [
inifile:=TIniFile.Create(inifilename);
$ T5 q& F" V# T) A/ J: X
我在这里绕了个弯子,写成
7 l" f! T; a& X9 t' [ h
inifile.Create(inifilename);
8 B: p$ O( u" G* d
3 F/ M3 K1 X8 V1 \- d
TShiftState用来检测CTRL,ALT,Shift,以及鼠标按键的状态,
8 V& z. s/ m' W
常常用在键盘或鼠标的事件处理程序之中。
\5 E. }4 g% _* o$ f/ j% T
' Y3 v: }3 P1 n
DCU文件(编译的库单元)的重用
9 {) Z3 d% v, H6 Y; O) Y# ]9 {) X9 Y3 u4 S
(1)在interface里的uses子句中引用。如Windows,Dialogs,
5 W& f6 k, u' }& O- i5 Y7 S
等等,要求被引用的DCU一定要放在Delphi 3\Lib子目录中。
% K1 s, S0 L- v# ] D6 E* o8 y* n
(2)在implementation里的uses子句中引用。如果是自行编写的
: X, D- j: E3 U; s
DCU文件,应采用这一方式,并将被引用的DCU文件放入当前
! a S8 B, g9 q( d) n5 e0 b
工程所在的子目录中。
* j p. G2 E; L3 u
executefile函数(在FmxUtils.DCU中定义)不能用在FormCreate
& _. E, E* r( d
事件中。真奇怪……
. V1 n, O2 v i1 p0 g( X
6 o* [" Z/ ^( J! u: r# [2 G
内置的版本号控制功能
5 u/ |8 f# G* y9 \+ {
在Project Options中的VersionInfo项里,有版本信息的定制,
: X; k# z3 B6 ]* h& z* j
包括一个有趣的版本号自动增加功能(Auto-increment build
! @ M* G; C9 v; `$ }8 {
number),即每Build一次,版本号中的Build Number加1。选中
, _4 Y) d) v0 b
Include version information in project,编译,用资源管
+ O; z/ h' n( b0 X! i1 e
理器里找到生成的.exe文件,点右键,查看“属性”一项,就
, B: t2 O, U% E8 c
会看到在属性中多了一页“版本”,里面就是你刚才输入的各
+ i1 ]$ n, \" D0 ?# F3 d7 q
项内容。
) J& D4 ~0 c. ? p8 C. t
. u) d+ _6 O0 i! Z @# y
: w+ x, R( I- q' p3 d3 z
定制Speedbar
% v5 Y% c* U$ _2 ]
右键点击左上角的加速键条(speedbar),选中Properties,
1 F* H" S5 K# H: Q8 N5 G" c
在列表框中找到你想要加入speedbar的命令按钮,将它拖到
9 U& P: P( {( U! V! i/ c
speedbar上的合适位置即可。如果speedbar上没有多余的空间
& C6 a: L9 v9 d/ k A7 Y; b- S1 n
来容纳新的按钮,可把鼠标在speedbar右框处变为双向箭头的
3 b L! H) j! {; R' _
形状,向右拖动一段距离,就可腾出空间。如想删除speedbar
! U, g- M( f3 i5 V) K
上的某个按钮,可简单地把它拖出speedbar的范围,就能删除。
; N' Z% u( ?8 H( b& _. T6 O2 l
5 q# i& _) h" a$ m, T" t
% c$ z+ K; ~5 j l' A/ J) v$ [+ Q& K
计算出的字段
4 T) Q5 w, i8 d- F
在写一个程序时,我要在DBGrid中显示出一个memo的部分信息,当我把那个
2 ]4 t/ v4 x8 R
memo字段放进去后,运行时只能显示出“(memo)”字样。从书上找到计算字
F/ q4 u3 @ J% I8 h
段的用法后,我在TTable中增加一个计算字段MemoHeader,宽度为40,在此
$ n. @0 l- w+ c& R
TTable的OnCalcFields事件中输入:
6 u- q& q* ? G0 s
with MyTable do
' F. O9 C7 s5 A# Z, ]; A/ d
FieldByName(‘memoheader’).asstring:=FieldByName(‘memo’).asstring;
' y* L1 b* u0 Y+ S* A
在DBGrid中放入MemoHeader,运行,OK!
3 X" r) f6 D9 h1 `! p
- ~( K; N2 g, u9 O9 F+ Q5 {
; `: d% x1 ^5 M" T
字段编辑器
6 q) d5 L; F4 T# E( U3 \
解决了上面的问题后,我继续学习字段编辑器的作用。原来,DELPHI通过字
$ S1 \! E& W- q [6 J4 n/ Z
段编辑器,近乎完美地实现了数据库的字段级的控制,这包括:
+ G5 v/ L0 v* l2 f
1)字段在DBGrid中标题、宽度、能否可见;
+ {& |: A6 p$ ]3 e, J0 U
2)字段的显示格式和编辑时输入的过滤条件;
1 R& Q8 G4 ?3 [! G
3)字段是否只读;
b! b$ H( s6 g& f
4)字段的类型:数据字段/计算字段/查询字段/内部计算字段;
0 r- A g: D* c/ j2 a$ \
5)字段的显示/赋值/修改等事件的定制。
9 q# x! R* N Z( N8 _3 }% ?
1 k: T4 f7 _% u7 z) N9 w& I
* P2 w! q' X, r4 U2 D; T
设计Form时的快捷键
: N4 T1 H/ H+ u( `& `1 q
Del 删除所选组件
: Q4 |! U& X. f. N/ T' l1 U
Esc 选择当前组件的容器(通常是Panel,Group或Form)
4 h0 Z4 q, f$ C) o+ {5 q7 m
F11 在Form或Unit和对象检查器之间切换
" G3 C6 J3 U" [$ S/ g
F12 在Form和代码编辑器间切换
' b& m: E _# z0 g1 }' J. [. c: K2 F
Ctrl-F12 显示“查看Unit”对话框
' [; T7 u; \9 r
Shift-F12 显示“查看Form”对话框
; M& m9 q( p6 K" B# Z% Y& u0 a
TAB 下一个组件
( c% n' E- `- F8 I6 a
Shift-TAB 上一个组件
* v0 c4 r' B3 h6 _4 H% e5 Z
方向键 选中此方向上最近的组件
6 T" [) D) V8 q( B0 `/ n
Ctrl-方向键 将所选组件移动一个点
+ t2 l' h m! `7 p# @/ Z
Shift-方向键 将所选组件改变一个点的大小
# O! v6 J2 F! g: f* j7 c$ Y' u
Ctrl-Shift-方向键 将所选组件移动一个格
3 V6 Y( k+ k* [% n& B. x4 J
Shift-click 按住Shift键再用鼠标点击组件,可以选择多个组件。
* p: p0 c, g: a& P- D ]
–= 下面这条是我摸索出来的 =–
$ h& H: ]+ N4 R6 @0 v
Ctrl-drag 按住Ctrl键在一个容器组件(如Panel,QReport,Groupbox等)
8 {9 `3 T+ d: }7 M# b. A* {
里拖动鼠标,可强制选择鼠标拖过的矩形框中的所有属于此容
, Q( L+ @! g5 n, r# B- _
器的可视组件但不包括该容器组件。
) d/ m2 T9 x+ x+ K3 y9 t X- y
2 G: p, p/ [8 S/ S
$ v9 e! H" @* |
使用QReport的若干经验
; J7 M+ T$ A- Q$ J5 ?
1)QuickRep1.DataSet:=query1
0 ^8 S: k! {+ D( f) b" b
不然无输出结果
+ w+ w5 H4 i* x) X% w( l- A6 n
2)从qrpt2man.doc中查知,格式化输出结果的方法是:
- J l, V, p# O; P
在QRDBText.Mask中设为.00;0,将使输出带两位小数。
. |" F' U. N- {
3)设置Group时,先加入一个QGroup,再加入一个QRBand,将QGroup的
$ A2 j+ Z% C/ F0 }8 k4 }
FooterBand设为刚才的QRBand,就可将其联系起来。
. ]* F' f& C+ F9 U0 ^& A; d$ }& G
4)在Group中打印的合计数,其ResetAfterPrint设为True,可实现分组合
! K- g' H2 O+ j1 m
6 t) l- V/ s) K& T2 H
format(‘%*.*f’,[8,2,123.456]); //等价于format(‘%*8.2f’,[123.456])
m( _2 p/ \% Q! l$ p! ]7 {$ C
format(‘%d %d %0:d %d’[10,20]);
9 k& {+ k6 R6 ^# J" T
$ R8 _% L3 b* A- ~- E! m- ]4 u
8 U7 E/ e) G/ X8 W( E! W1 x' n+ v$ n
3 V; }% s* `2 h v' u4 O1 E
播放一个wav文件
) f9 T- a. Y$ l# Q4 Z
use mmsystem;
# y: G* V0 z9 i. d0 r
SndPlaySound(‘hello.wav’,SND_FILENAME or SND_SYNC)
) \6 z& k% a/ k* _& {
$ v/ F2 V0 r% E( Y
使你的form适应不同的显示分辨率
6 y1 J3 A p$ n$ J d/ L6 K! z
假设你在800*600的分辨率下设计的form,第一步:
E( R4 ]# O- m9 O* w# k9 p
inplementation
: r/ V$ N3 D& E; b# _
const
8 ?4 K) c6 _- P' X' W! y
ScreenWidth: LongInt = 800; {I designed my form in 800×600 mode.}
) {5 F1 M; K9 U5 f" D- J% s4 }
ScreenHeight: LongInt = 600;
0 e& u% `2 e" Z3 e
/ g W. f) v$ M# D w! O
{$R *.DFM}
1 _3 Y5 B7 x- }1 d
# b4 ? e. _" Z- f
procedure TForm1.FormCreate(Sender: TObject);
: T1 o+ B6 t9 U
begin
. b Y) m1 p. A! Y+ @ f
scaled := true;
# u. }( o# K" o
if (screen.width <> ScreenWidth) then
; C" ?, ~ K! d" B/ N1 o, p7 Z, D
begin
) ?1 g( N. K/ t* ^+ ^$ O) P4 q+ a
height := longint(height) * longint(screen.height) div ScreenHeight;
$ z, `* ]# D5 n" x* p
width := longint(width) * longint(screen.width) div ScreenWidth;
+ _ `2 Z, e* v u2 S
scaleBy(screen.width, ScreenWidth);
7 x% \1 H3 r6 E2 k; l
end;
! N( L0 F; D2 A; L% `
end;
% X g/ L3 r$ s' j) t/ p# D' w
( [% c& A- Y& ^+ N5 {# r% y$ |/ y' r) K
下一步,要让每个子控制的字体改变到合适的大小:
5 p7 A* j* @4 s
type
" D+ T( b2 J P2 s5 C
TFooClass = class(TControl); { needed to get at protected }
- W" H: _! h: l5 u; l. @% @
{ font property }
3 I1 h* N; N/ N' d
5 M& \1 L% w @
var
* ~0 {* z/ Q5 j/ B% I
i: integer;
N) A7 x& {; Z) {& {( ` K
begin
- K/ h; G1 _9 N6 O& o4 K* e' t
for i := ControlCount – 1 downto 0 do
0 A& P7 }. z: R2 ]9 I% w3 K' m
TFooClass(Controls
).Font.Size :=
4 O* h9 t( m3 y+ j
(NewFormWidth div OldFormWidth) *
( |, i7 G3 h) s! V5 u; k
TFooClass(Controls
).Font.Size;
. t m" I0 C: {* i5 D) _" e5 W
end;
0 m% Y: c2 D& B8 K# {2 x1 q6 z
2 v; P: P# ?9 i x- ?
用raise引发一个错误处理例程
* {9 | z7 w; P1 f$ p
示例:先给出下面的定义
: \" h( c3 M! b7 ]$ q" {, o1 _
type EPasswordInvalid=class(Exception);
4 U$ x+ t0 H! \
这样你就可以随时引发一个”password invalid”的例外:
9 {5 W4 I6 X9 J+ a( |2 o- i
if Password<>CorrectPassword then
4 `$ I, E" I' z6 h a9 s! D
raise EPasswordInvalid.Create(‘Increect Password entered’);
7 M; b# A+ M) R5 k2 l+ N, }2 T" Z
运行后,出现信息框
, M5 S& u, V2 N7 _" X- W
Project Project1.exe raise exception class EPasswordInvalid
$ m4 \% V* C, \% i: B1 z* M
with message ‘Incorrect Password entered’. Process stopped.
2 R" G, U# H# H7 d( s0 ~
Use step or run to continue.
4 Z( `9 k2 O: T% a
再按Run按钮,出现一个信息框:
6 s3 F. {/ D) v0 m9 F
Incorrect Password entered.
: P) ~$ h$ C! h0 E
5 u ]) I8 _) r2 } |
4 V; o4 q; @& W
从DEMO例程中学到的若干小技巧
7 N+ X. j; d# g* _& `/ H
在demo\internet\http\webbrows\main.pas中,
- p5 R' ]' ^# A
procedure TForm1.DocumentSourceClick(Sender:Tobject);
! S7 Y* x5 p+ F3 \7 D* J
begin
- m: {% `/ o5 Q$ k( [
with DocSourceForm do
& C1 G! b1 x7 c4 o3 k7 o
begin
: L' `; Q$ h- {0 u) X+ a
show; // 显示HTML源码的FORM
" x c+ o6 Z+ n8 j1 |: p3 K# E1 T
Memo1.lines.clear; // 清空memo1中内容
( a" ]: G& j0 c- c
Memo1.lines.add(HTML1.SourceText); // 植入源码
4 K/ \/ S* i! _ C
Memo1.SelStart:=0 // ***
" ]$ b) W3 N, j+ ?
SendMessage(Memo1.Handle, // Memo1的窗口句柄
b6 }: q8 g/ u0 r+ Z8 K& [
EM_ScrollCaret //将Edit Control中的caret光标滚动到视野中
* H/ L {- H7 L2 O0 B3 y+ p0 x
0,0 //这两个参数暂不使用
. S* }- P4 Q/ v' `
end;
* `( @! v( ] |. L/ i
end;
0 L5 r# O8 W/ h- v1 S4 W' H1 @
(此SendMessage系一WinAPI调用,给一个或一组窗口发送消息,直到
, u* z. g$ Z- q, C5 x( h4 n$ Y! |
相应窗口处理此消息后才有返回值。相似的另一函数为PostMessage,
# j O* w7 ?0 n1 [$ C
它将消息放入消息队列中后立即返回。)
, \0 }2 }: y7 ? P+ u8 W4 i
*** 清空当前选择并将光标移动到指定字符(0代表第一个字符)。如同时
6 f) z x7 `% p/ ~# p( [! g
设memo1.sellength为一非0值,可选择一段文本。
: d& r3 K% s7 N8 B2 j" W
1 K' ], x; `( F. }6 C+ `: N
! X% K) W7 [0 g2 N
奇怪的I/O error — 我在开发过程中发现下面这两条语句
. ~! h4 D. j+ g6 L+ S
assignfile(fDesc,CDDatadir+describefile);
( |6 W2 X5 w8 T$ Q
reset(fDesc);
2 @2 T m4 h) m7 _' d5 `
每当我第一次运行到这里时,总会出现 I/O Error 183 的错误.
& f: X4 w+ F) D& D
最后我想这也有可能是没有清除 ioresult 的原因.在两句之间加入
- k f7 y1 d0 y! \$ z
if ioresult<>0
' v, R6 w$ O2 N
then;
- O% M+ q3 j' ?5 L# r) G: w( Q
oooook! 可以了.
7 a% F: {3 X9 F6 N% V
+ ~: @" Y7 Z' X0 p
8 W2 m# S; Q" c4 U- D& }4 Y
值得注意的I/O error
b: X# V7 F2 @6 e
AssignFile(F, fname);
. s/ ?) P& _+ h2 Q% |
Rewrite(F);
' d/ X2 K$ l/ k' t1 a5 q. u4 K* l
当文件 F 经 Reset(F)打开的情况下, Rewrite(F)会引发一个异常: I/O error 32
# C+ y, l# M6 k% }* S# U
反之,经 Rewrite(F)打开, Reset(F)也会引发同一个异常.
% D/ Q! z4 Q& j# K
Reset(F)两次,closefile(F),再Rewrite(F),或反之,也会引发同样异常.
& E- T( K* k% x2 t9 x! K
! ]: U, W8 @, N5 L# @$ A
$ K" D6 N+ j& u, S( B5 r
1 L6 y9 W* q1 B
string和pchar的相互转换:
9 o/ g0 a- `# }
string –> pchar: pchar(s
% o" e; E8 v' s
tr:string);
: a% p8 A5 ^( e( f3 V- }! j7 z' N
pchar –> string: strpas(p:pchar);
8 B& |; @' {! ]- x
3 z3 d7 {. u& N, P# y
5 }$ g+ z# l$ [9 Y
+ _ Y- M* p {! _9 f! F' C
在Delphi代码中定义数据库
% V: m h8 H9 i/ u
procedure tform1.create_tbl;
5 E9 V' z8 B, @1 a8 F# C
var tbl:ttable;
3 H7 L; a3 Y- Y- e! w, G9 R9 x
begin
6 y0 p$ ^% Z7 a: U. g
tbl:=ttable.create(self); // 如没有声明中的”tform1.”,Delphi不认这个self
5 }" L0 O7 [' y3 b* D2 v4 p. H. i# n% o
with tbl do
! k9 C, W+ l3 B( m. a1 K2 J* }3 r
begin
1 b5 i$ e- n) G, E O, n' ?
datebasename:=;dbdemos’;
: c3 E# M% c- Q0 j
tablename:=’my_tbl’;
: B2 j& f9 s& ]- u" B4 f3 q# y
with fielddefs do
, F: w; h3 _! [0 o B `9 O
begin
% p. n7 `! e* o" O" z
clear;
1 h$ j* }6 L! }4 v1 k& i
add(‘No’,ftInteger,0,false);
0 L# \/ i G$ s( g
add(‘Name’,ftString,0,false);
0 X+ x. t5 _1 ?& D' I; P- B! ^
…
' G) Q; f2 _/ U9 P1 F1 X N
end;
8 ?7 s: ]& A5 N7 C! y
with indexdefs do
0 j! T [- y8 m6 i5 d
begin
' S9 A% L1 v- d" O+ b* i3 R3 E! }5 g
clear;
/ N H8 g, s1 }2 q4 m
add(‘primary’,'no’,[ixPrimary,ixUnique]);
& F- p& ?0 U8 `) V. Y5 \
…
: u# O3 x3 N1 v t# _ i
end;
8 h5 R- m( N+ I3 S0 I7 |/ ]# g
CreateTable;
3 x6 w4 C# @% \* g% {" J
end;
' n% V) v- o4 t
end;
: Y- u! ^# C- E# p- _4 J
: {2 x" \( c( q: i: @ d
& a2 C S, f( I
string、TStrings、pchar的相互转换(这里是我的个人经验)
% n& r s/ m% L2 M, M9 T* Z* W: O. c
假设有如下定义:
% T7 f& J- V {) l9 J
var
( D/ F3 U* s! R( F% \
p:pchar;
; _/ _: `: q1 C2 V" b8 U
s:string;
% r, b& c! ? T+ o+ U
ss:tstrings;
, W: W0 D) Q$ A" z, k7 w
begin
; C+ _. p' D. u6 v
ss:=tstringlist.create; // 开始时一定不要忘记创建ss
* D3 z3 `0 j5 u/ Y
ss.text:=s; // string –> tstrings
7 Q* D3 O% i, v1 g2 O* q
s:=ss.text; // tstrings –> string
# f' \" p. |6 m& b6 r
p:=pchar(s); // string –> pchar
3 M) L2 G- |* m6 p% p' v
s:=p; // pchar –> string
3 |6 b8 U* L/ l7 ]& ]/ I
showmessage(s); // 合法语句
9 X5 a8 S5 t' Z0 b7 a4 [+ F
showmessage(p); // 合法语句
6 C3 ^7 J5 T2 ?2 v- v: M7 v* f
… …
h" k# T7 N I1 o2 Z# ]5 i7 R
ss.free; // 最后还要记着释放ss占用的资源
) w$ n( Y P+ a
end;
: ~ n2 j6 F; B
- l1 n0 `* G' D( n
7 A% ?, J. `& M9 e! L$ z2 k
. Z E4 n; A9 |8 O- b
在设计Menu时,常用的ShortCut可从下拉菜单中选取。但我发现可选的ShortCut有些不在列表中,如ESC,Ctrl-Shift-A等。我试着在ShortCut项的右边输入:ESC,竟然成功了。再试Ctrl-Shift-A,这回Delphi自动把它变为Shift-Ctrl-A
歡迎光臨 幸運草之戀 (http://discuz.segaa.net/)
Powered by Discuz! 6.0.0