DELPHI积累

Delphi 中strpcopy 可以把一个字符串拷到一个CHAR型的数组

Var

Ary : arrary[0..100] of char;

S : string;

Ret : integer;

Begin

Strpcopy(ary,s);

For I :=0 to 99 do

Ret := ret xor integer(ary[I]);

Result :=inttohex(ret,2);

Result :=lowercase(result);

End;

用strpcopy也可以把一个字符串拷到一个CHAR型的数组的指定域function formatinttostr(icount :integer;len :integer) :string;

var

str:string;

strLen : integer;

iAry : Array[0..20]of char;

i : integer;

begin

str := IntToStr(iCount);

strLen := Length( str );

if ((Length( str ) > Len) or ( Len >= 20 )) then

begin

FormatIntToStr := '';

exit;

end;

for i := 0 to Len - strLen - 1 do

iAry[i] := '0' ;

strPCopy(@iAry[i],str );

iAry[Len] := #0 ;

FormatIntToStr := StrPas(iAry);

End;

在查询语句中加入条件时间的判断

Query1.sql.Add('select * from yourtable mytable where mytable."Date"=:currday'); Query1.ParamByName('currday').AsDate:=now;

Query1.open;

如果你的字段名是关键字(如date),请用双引号引上。

在DELPHI中执行系统函数

用WINEXEC或SHELLEXECUTE,但WINEXEC不等待的。

在使用静态的多页面功能时,可以使用TNOTEBOOK和TTABSET联用在开始化时设置TABSET的TABINDEX NOTEBOOK的PAGEINDEX等于TABSET的TABINDEX

在TABSET的CLICK事件中设置TABSET的TABS等于NOTEBOOK中的PAGES

创建多页面编辑器时要注意的问题

要创建多页面编辑器,必须从TPage的父件(Parent属件)创建相应编辑部件。但在动

态创建页面时,TPage只是一个与字符串相联系的TObject类,不能写成:MemoParent := Notebook1.Pages.Object[ ];

在Delphi中,宣称对象和创建对象都是用指针来标识,因此可用无类型指针进行指针传递。

var

Pi : Pointer;

begin

Pi := Notebook1.Pages.Object[];

Memo.Parent := Pi;

end;

这样就可在TPage上动态创建编辑部件了。

在动态创建的窗口也能用WITH 。。DO 的方法

if OpenFileDialog.Execute then

with TEditForm.Create(Self) do

Open(OpenFileDialog.FileName);

end;

在程序中要使用打印和剪贴的动作时,需要包括以下代码

uses Clipbrd, Printers;等

字符串属性的对象:

访问Strings属性Objects属性

加入项目Add 方法AddObjects方法

插入项目Insert方法InsertObjects方法

项目定位Indexof方法IndexofObject方法

问题:

在STRINGGIRD中不能截获对某个单元的CLICK事件,而且不能在CELLS中嵌入如COMBOBOX等控件

解决办法:

做隐含的EDITBOX或COMBOBOX来完成需要的工作,但这样不是很方便,需要在处理的时候屏蔽掉原来的STRINGGIRD并且显示需要的多个EDITBOX和COMBOBOX来完成系列的操作。

不知道是否有什么更好的方法。

事件发送者句柄要注意的问题

在多个控件调用同一个函数或过程时,需要注意发送句柄者对象拥有者的区别。

在DELPHI中,每个事件都有自己的事件句柄来识别所传递的消息和事件,以次来区分不同的动作(可以在一个函数内实现,可以做到代码共巷)。

With Sender as 某对象实体do

Begin

…..

end;

虚拟键盘的应用

在DELPHI中要注意软键盘的应用,可以节省时间和代码量

虚拟键定义在\...\Source\Rtl\Win\Windows.Pas中,

包括所有的键,除字母和数字外,

字母和数字的键值说明如下:

{ VK_0 thru VK_9 are the same as ASCII '0' thru '9' ($30 - $39) }

{ VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' ($41 - $5A) }

和键盘相关的事件有:OnKeyDown、OnKeyUp和OnKeyPress,

产生顺序如下:

1、OnKeyDown

2、OnKeyPress

3、OnKeyUp

不产生ASCII字符的按键不会触发OnKeyPress事件

使用不可见控件TSTRINGLIST

由于TstringList在控件栏上没有选项,它一般只能自己的定义,并在程序中生成

ALIST :TstringList;

。。

procedure a( …);

begin

HistoryList := TStringList.Create;

End;

另外在使用这个控件时,需要定义一个INDEX变量,用来定位。

自定义过程的定义和使用:

自己定义的过程要定义在一个FORM的V AR中而不能定义在它的TYPE中

调用时可以直接进行。

转义符号的使用:

在SQL语句中要使用LIKE等匹配或其他方式,需要在变量后加某个字符或其他变量,需要转移符对变量进行分离。

普通的SQL语句如果要是

select * from servs where type_index like 变量;

在DELPHI中就需要以下格式进行:

'select * from servs where type_index like '+''''+content.Edit2.text+'%'+'''';

在时间ON_CHANGE中注意的问题:

如果在CHANGE事件中定义了一些操作,譬如SELECT 某些字段的话,而条件来自于CHANGE事件发生者的TEXT域,那么就不能对它进行清除了,如果一清除该实体的TEXT 域,将又发生一个新的匹配。

那怎样能够避免这样的情况呢,ON_KEYDOWN事件替换CHANGE事件

继承的应用:

如果在一个应用程序中要多次用到基本相同的FORM,这样可以考虑建立一个基本的模版FORM,其他应用的FORM在它的基础上进行继承和延伸。

这样可以提高代码的使用率和良好的模块性。

文件传送的长度问题:

在DELPHI中如果要发送比较大的文件或图象,用判断Len的方法可不好。

最好先发送文件长度,然后再发送文件。或者直接发文件,发完就断掉连接。

记录移动的对象:

在DELPHI中,掌管记录移动事件的对象是DA TASOURCE控件。

SOCKET发送单行和多行的问题:

在DELPHI中可以把MEMO。LINE。TEXT作为一个字符串发过去,而不要去管它有几行,最多有几个#13#10等字符,在接收程序中把它过滤就可以了。如果只要发送MEMO 的当前行可以如下操作:

if Key = VK_Return then

Socket1.Socket.Connections[0].SendText(Memo1.Lines[Memo1.Lines.Count - 1]) 或者用STREAM方法,DELPHI中大部分的控件可以转化成STREAM的。

利用控件TNMStrm完成文件转化成流的发送以及接收

procedure TForm1.Button1Click(Sender: TObject); ---发送的按钮,选择一个文件进行发送var

MyFStream: TFileStream;

begin

If OpenPictureDialog1.Execute then

Begin

NMStrm1.Host := Edit2.Text;

NMStrm1.FromName := Edit1.Text;

MyFStream := TFileStream.Create(OpenPictureDialog1.FileName, fmOpenRead);

---把读出的文件转化成文件流的格式

try

NMStrm1.PostIt(MyFStream);----把文件流进行发送给SERVER

finally

MyFStream.Free;

end;

end;

end;

procedure TForm1.NMStrmServ1MSG(Sender: TComponent; const sFrom: String;

strm: TStream);

var

MyFStream: TFileStream;

begin

If FileExists('.\tmp.bmp') then DeleteFile('.\tmp.bmp');

----如果已经有这个文件,就删除,这只发生在已经知道要传送的文件名的情况或某些临时文件。

MyFStream := TFileStream.Create('.\tmp.bmp', fmCreate);

----创建文件

try

MyFStream.CopyFrom(strm, strm.size);

----把读出的流复制到创建好的文件中

finally

MYFStream.Free;

end;

end;

如何动态更新DBGrid的颜色

DBGrid控件是一个有许多用户接口的显示数据库的控件,以下的程序告诉如何根据显示的内容改变字体的显示颜色。例如,如果一个城市的人口大于200万,我们就让它显示为蓝色。使用的控件事件为DBGrid.OnDrawColumeCell.

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect:TRect;DataCol: Integer; Column: TColumn; State: TGridDrawState);

begin

if Table1.FieldByName('Population').AsInteger > 20000000 then

DBGrid1.Canvas.Font.Color := clBlue;

DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);

end;

上面的例子是简单的,但是你可以根据自己的需要扩充,例如字体也变化等,甚至你可以调用画圆的函数在数字上画上一个红色的圆圈。

但是,怎样在DBGRID中把一个CELL变成一个DBCOMBOBOX呢,这样可以使编程简单很多啊,是否应该自己做一个部件呢?

或者是否能捕捉到DBGRID(STRINGGIRD)中的CELLS的FOCUS???

用INSERT CONTROL?

在DELPHI中定义指针变量:

//?在指针定义之前先定义一个指向这个指针的变量,以后可以用这个变量来定义变量。Type

PSortArray = ^TSortArray;

TSortArray = array[0..114] of Integer;

TSortThread = class(TThread)

private

FBox: TPaintBox;

FSortArray: PSortArray;

FSize: Integer;

FA, FB, FI, FJ: Integer;

procedure DoVisualSwap;

protected

procedure Execute; override;

procedure VisualSwap(A, B, I, J: Integer);

procedure Sort(var A: array of Integer); virtual; abstract;

public

constructor Create(Box: TPaintBox; var SortArray: array of Integer);

end;

使用*.INI文件:

要利用.INI文件做程序有关数据的存储工作,就需要能读和写.INI文件,有如下方法从.INI文件中获取字符串

var

strResult:pchar;

begin

GetPrivateProfileString(

'windows', // []中标题的名字

'NullPort', // =号前的名字

'NIL', // 如果没有找到字符串时,返回的默认值

strResult, //存放取得字符

100, //取得字符的允许最大长度

'c:\forwin95\win.ini' // 调用的文件名

);

edit1.text:=strResult; //显示取得字符串

从.INI文件中获取整数

edit1.text:=inttostr(GetPrivateProfileInt(

'intl', // []中标题的名字

'iCountry', // =号前的名字

0,// 如果没有找到整数时,返回的默认值

'c:\forwin95\win.ini' // 调用的文件名

));

向.INI文件写入字符串

WritePrivateProfileString(

'windows', // []中标题的名字

'load', // 要写入"="号前的字符串

'accca', //要写入的数据

'c:\forwin95\win.ini' // 调用的文件名

);

向.INI文件写入整数

WritePrivateProfileSection(

'windows', // []中标题的名字

'read=100', // 要写入的数据

'c:\forwin95\win.ini' // 调用的文件名

);

如何定时关闭WINDOWS:

写一个定时程序,在时间到时触发关机开关。

控制WINDOWS的开关:如关闭WINDOWS,重新启动WINDOWS等, 都是通过函数ExitWindowsEx(UINT uFlags,DWORD dwReserved)来实现。

首先定义常数

const

EWX_FORCE=4; //关闭所有程序并以其他用户身份登录

EWX_LOGOFF=0; //重新启动计算机并切换到MS-DOS方式

EWX_REBOOT=2; //重新启动计算机

EWX_SHUTDOWN=1;//关闭计算机

运行时给How赋值,让他等于EWX_SHUTDOWN或其他,调用以下语句

ExitWindowsEx(How,0);

关闭没有被激活的窗口:

在应用程序中,如何关闭已经被转移焦点的FORM,例如:有两个按钮各自产生一个FORM,第一个产生的FORM就被转移焦点,当然可以在按第二个按钮时判断是否第一个FORM是否存在,存在则将之关闭,另外一个也如此,但这样的方法很是老土,一般程序员不会喜欢的,而且也许还有其他情况下不能如此做的。

我们可以通过检测句柄来确定当前WINDOWS的工作任务是否与目前的FORM的应用程序一致,如果不一致就关闭以前或以后的任务。

procedure TForm1.AppDeactivate(Sender: TObject);

var

hw: HWnd;

CurTask: THandle;

WndStyle:Longint;

begin

CurTask:=GetWindowTask(handle);

hw:=GetWindow(GetDesktopWindow, GW_CHILD);

while GetWindowTask(hw)<>CurTask do

hw:=GetWindow(hw, GW_HWNDNEXT);

while (hw<>handle) and (GetWindowTask(hw)=CurTask) do

begin

PostMessage(hw, WM_Close, 0, 0);

hw:=GetWindow(hw, GW_HWNDNEXT);

end;

end;

把控件转化成流文件进行传送:

这样可以避免图象传送引起的各种问题,可以把控件转化成流文件,接收方根据接收到的流文件转化回图形文件。

procedure WriteComponentResFile(const FileName: string; Instance: TComponent);

function ReadComponentResFile(const FileName: string; Instance: TComponent):TComponent;

为应用程序创建HOTKEYS:

第一步:

设置FORM的KeyPreview := true;

第二步:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

if (ssCtrl in Shift) and (chr(Key) in ['A', 'a']) then

ShowMessage('Ctrl-A');

end;

当然也可以利用其他值,上面只是一个简单的例子。

动态创建控件:

动态创建控件第一件事就要登记注册需要创建的类。这个可以用RegisterClass(),RegisterClasses() or RegisterClassAlias() 等函数来实现。

procedure TForm1.FormCreate(Sender: TObject);

begin

RegisterClasses([TButton, TEdit, TMemo, TLabel]);

end;

在创建控件中可以使用FindClass() 函数来返回要创建的部件的类关联。

procedure TForm1.CreateClick(Sender: TObject);

begin

SomeComponent:= TComponentClass(FindClass(ClassName.Text)).Create(Self);

(SomeComponent as TControl).Parent := Self;

end;

在创建以后怎样利用这个新控件呢?

使用SetXXXXProp() 函数来设置控件的值.

使用GetXXXXProp()函数来获得控件的值

用GetPropInfo来获得控件的属性?

在DELPHI中添加一条记录可以用APPEND ,这不同于一般的数据库,增加记录只能用INSERT。

inifile:=Tinifile.Create('..\User.ini');//

datamodule1.Query1.Active := false;

datamodule1.Query1.SQL.Clear;

datamodule1.Query1.SQL.Add('select * from Alog');

datamodule1.Query1.Active := true;

datamodule1.Query1.Edit;

datamodule1.Query1.Append;

datamodule1.Query1.FieldValues['Opid']:=inifile.ReadString('User','Id','');

datamodule1.Query1.FieldValues['Summary']:=summary;

datamodule1.Query1.FieldValues['Time']:=now;

datamodule1.Query1.Post;

datamodule1.Query1.Refresh;

datamodule1.Query1.Close;

使用数据导航条:

在使用数据导航条时,注意不要用Query.,如果用了Query.部件,那将只能进行查询而不能进行修改了,所以在DataSource中的DataSet应该设置为Table,而不是Query.

把记录组合成文件:

假设A是一个RECORD

MFILE :FILE OF A;

MRECA:A

这样在打开文件MFILE后就可以

READ(MFILE,MRECA)或WRITE(MFILE,MRECA)

如何在StringGrid控件中让Enter键作用象Tab键

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);

{ 在FORM的OnKeyPress事件中插入,注意将Form的KeyPreview属性设为True } begin

if Key = #13 then

if not (ActiveControl is TStringGrid) then begin { 如果不是TStringGrid }

Key := #0; { 清除按键}

Perform(WM_NEXTDLGCTL, 0, 0); { 否则移到下一Control上}

end

else if (ActiveControl is TStringGrid) then

with TStringGrid(ActiveControl) do

if selectedindex < (fieldcount -1) then

selectedindex := selectedindex +1

else

selectedindex := 0;

end;

另一种更简便的方法:

在StringGrid的KeyPress事件中写入

if Key=Chr(VK_RETURN) then

SendMessage(StringGrid.Handle,WM_CHAR,VK_TAB,0);

*在D2,D3中用时去掉Chr()函数。

如何给TListBox加上水平的滚动条?

Delphi 的TListBox元件自动实现了垂直的滚动条,当ListBox不能显示全部的菜单(Item)时,这个垂直的滚动条就会出现。然而,当菜单的宽度比ListBox宽时水平的滚动条却不会出现。以下的程序就是处理这个问题的。

在你的Form的OnCreate事件中添加以下代码:

procedure TForm1.FormCreate(Sender: TObject);

var

i, MaxWidth: integer;

begin

MaxWidth := 0;

for i := 0 to ListBox1.Items.Count - 1 do

if MaxWidth < ListBox1.Canvas.TextWidth(ListBox1.Items.Strings[i]) then

MaxWidth := ListBox1.Canvas.TextWidth(ListBox1.Items.Strings[i]);

SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, MaxWidth+2, 0);

end;

以上的代码首先得到ListBox中最长Item的长度,然后用LB_SETHORIZONTALEXTENT 消息设置ListBox的水平滚动的宽度,宽度加2是为了给右面留2个点的边。

相关文档
最新文档