1- Tlistbox控件
重要属性items.*
举例,界面设计如下左,执行结果如下右:
代码为
procedure TForm1.Button1Click(Sender: TObject);
begin
edit1.Text := listbox1.Items.CommaText;
edit2.Text := listbox1.Items.Text;
edit3.Text := listbox1.Items.GetNamePath;
edit4.Text := listbox1.Items.Strings[1];
edit5.Text := listbox1.Items.DelimitedText;
edit6.Text := listbox1.Items.Names[1];
end;
由执行结果知,CommaText把各行用逗号隔开,Text获得所有行数字符且不隔开,Strings[i]获得i行的字符。
2- Checkbox控件
Alignment决定文字和框的左右布局;state属性里有个Grayed状态,为灰色选中状态,与Enabled:=false不同的是它可以在程序运行的时候进行操作;AllowGrayed属性为True时候,控件有三种状态:选中、未选中、选中但变灰;
3- RadioGroup控件
Columns属性设置radobutton的列数;
4- TmainMenu控件
Action属性;AutoHotKeys属性自动配置快捷键;
birmap属性为某个菜单标签添加图标;
Break属性给菜单分栏:mbBarBreak-分栏有竖线,mbBreak-只分栏无竖线,若要从末各标签开始分栏,则设置该标签的Break属性;
Caption属性设置为短横线时为分隔横线;
Checked属性为True时为标签添加对勾;
ShutCut属性为标签添加快捷键,并在标签右边显示;
模板应用:右击主菜单,Insert..
保存模板:与上类似,Save As..
5- PopMenu
应用步骤:添加控件,然后设置PopMenu属性指向动作空间;
Additional页
1-Navigator控件:
Flat属性设置3D/2D效果;dragCursors设置拖动是显示的符号,drag mode/dragkind决定是否可以进行拖动操作;
2-Additional页的BitBtn控件
Kind属性设置按钮图片类型,layOut设置图片在按钮上的布局;Glyph属性自定义图片,图片路径c:\...Borland shared\Images
3- Additional页的SpeedButton控件
Glyph属性自定义图片,图片路径c:\...Borland shared\Images; Flat属性设置3D/2D效果;最大的优势在于鼠标指向它的时候呈立体效果;
4.- Additional页的CheckListBox控件
Items属性中写入项目,但是项目前具有CheckBox的形式,可以进行项目选择;
判断第k个项目是否被选择采用如下语句 :if checklistbox.checked[k] = ture ?,与若干单独的checkbox比较优势在于可以统一编程,不在需要对每一个checkbox单独去编写程序!
5. Additional页的橡皮筋控件Spliter
作用是分割窗体,是一自动行为控件,无需任何时间代码。
使用过程为:放置控件,设置Align属性,调整Height或width属性。
6. Additional页的静态文本控件StaticText
功能与Text 类似,但通过设置Bevelkind, Bevelinner, Bevelouter和borderstyle属性可以加强外观修饰功能!!
7. Additional页的控制棒控件ControlBar
功能:强大的控件修饰功能,是制作加速键面板的有理工具,譬如office中的工具按钮等。
8.Tsahpe 控件
三个主要属性:Pen属性,Brush属性,Shape属性。Pen属性决定边框显示,包括
LabelEdit控件
Label 和Edit的组合;
Win32页
TabControl
重要属性有:Tabs属性创建页数,Font修改字体属性,Style更改页面风格,Tabposition设置按纽方向、布局。
TrackBar跟踪条/进程条ProgressBar
对任务的执行状态进行跟踪。
重要属性为:
a. min,max,设置举例:trackbar1.Min := 0, trackbar1.Max := mediaplayer1.Length;
b. position 指定跟踪对象,如trackbar1.Position := mediaplayer1.Position;
c. TickStyle为跟踪类型选择,一般选择tsAuto。
日期时间控件 DataTimePicker
功能:拾取系统时间、日期,并以对应格式输出
重要属性:
a. date,拾取的时间。
b. Time,拾取的系统时间 举例如:button2.Caption := TimeToStr(DateTimePicker1.Time);
c. DateFormat:dfShort为短格式,dfLong为中文长格式;
MonthCalendar控件
功能,直接显示月历,
树结构目录查看控件TreeView
重要属性:
Item>>生成树结构,HotTrack实现热追踪;Font属性设置树结构的字体属性;
AutoExpand: Boolean;
HotTrack: Boolean; 实现热追踪
Selected: TTreeNode;
Read Selected to access the selected node of the tree view. If there is no selected node, the value of Selected is nil.Set Selected to set a node in the tree view.
ShowButtons: Boolean;是否显示树结构钱的+、-号
具体使用如下
Var
node :Ttreenode; //定义树节点类型
pnode : ttreenode;
begin
//增加选中节点的子节点,并展开
node := treeview1.Selected; //支点选择
treeview1.Items.AddChild(node,'增加节点'); //增加子节点
node.Expanded := true; //展开支点
//增加选中节点的同级节点
pnode := treeview1.Selected.parent; //指向父节点
treeview1.Items.AddChild(pnode,'增加的同级节点'); //增加子节点(该节点的父节点的子节点为该节点同级节点)
end;
标题头控件headerControl
制作标题头
重要属性:
a. setions:输入标题文字;
b. style:有flat\buttons…等式样,其中Flat式样不接受sectionclick事件。
c. HotTrack
状态条StatusBar
功能:显示系统运行时的提示信息
重要属性:
a. simleText:当为单栏状态条时,显示信息,应用如:StatusBar1.SimpleText := datetostr(date);
右击StatusBar控件,打开Panel Editor,可以设置多栏状态条和各自的宽度。应用如StatusBar1.panels[2].Text := datetostr(date);(使用Timer控件以保持和系统时间的同步性)
ToolBar
功能:开发快捷键
右击生成按钮和分割符;对应的按钮的Style属性选择按钮属性,共5种;按钮的MenuItem属性选择关联的下拉菜单,按钮的PopMenu属性选择关联的右键菜单。Hint和ShowHint配合使用显示提示(Hint输入提示文字,ShowHint设置为true)
实际使用步骤:1.在Win32页中拖入imagelist控件,并双击打开添加图片;2.添加toolbar控件,设置hotimages和images属性为imagelist空间,然后在上面添加工具按钮,并设置工具按钮imageIndex属性,下一步就设置menuItem属性选择关联彩单。
9 CoolBar
右击生成Bans;
D7的TXPManifest控件
如果你的操作系统是XP,将TXPManifeS加入到窗体上,就可以使窗体以及其他所有孔件实现XP效果。如果不是XP系统就没有任何用处。
System页
OLE(对象联结和嵌入容器)
右击控件选择Insert Object 弹出Ole Insert Object对话框,促啊如OLE服务器对象。常见命令如下
OleContainer1.InsertObjectDialog;//弹出Ole Insert Object对话框
OleContainer1.DestroyObject(); //程序关闭的时候保证对象的销毁
ActiveX(页)类控件
Chartfx 控件
使用步骤:1.拖放控件;2.把控件的Toolbox属性设置为True,从而打开工具棒;3.右击打开“特性”……,其中label标签中可以添加图标的标题;
重要属性:
Chart3D:是否采用3D绘图方式
ChartType:选择绘图类型,如柱形图,折线图等
PalleteBar:面板工具显示否(用来修改背景颜色和坐标平面颜色),选True或者False;
PatternBar
问题:如何动态地添加数据,把它很好地运用到自己的程序中来?
F1book控件(Excel工作表控件)
拖入控件,双击行、列标题可以修改行列标题,右击work designer可以设置属性,其中gernal标签下的Enable Protection可以设置用户是否可以编辑表格中的数据。
Vtchart控件(excel立体图控件)
Win3.1页
资源管理器的制作(实例)
界面以及运行结果
制作步骤,在win3.1页中加入DriveComboBox1,DirectoryListBox1,FileListBox1,FilterComboBox,然后连接各控件(设置DriveComboBox1的DirList属性为DirectoryListBox1,DirectoryListBox1和FilterComboBox对filelist属性为FileListBox1),最后打开FileListBox1的Filter属性设置过滤特性,形式如下
相关控件的重要属性:
Filelistbox控件:
FileEdit:与Edit控件相关联,显示选中的文件名;
Mask:屏蔽文件;
ShowGlphy :显示文件图标。
DirectoryListBox控件:
DirLabel :与Label控件关联,在Label控件中显示文件夹带路径;
Filelist :和Filelistbox控件:相关联。
Sample中的Shell Control 控件
,就是ShellTreeView,ShellListView,ShellComboBox和ShellChangeNotifier控件。
第三方控件
1. 托盘控件TrayIcon(D:\Delphi第三方控件,安装后位于Samples页中)
步骤:第一步,拖放控件至窗口,然后再添加一个ImageList控件,且添加图标
第二步,设置Icons属性为Imagelist,Animate属性和AnimateInterval控制动画效果;Visible控制可见性;Hint显示提示信息。
delphi应用
模板应用
1新建窗体file\new\Others…>>Form,如下
各个窗体为:
2新建对话框file\new\Others…>>Dialog,如下
可以建立如下对话框:密码输入;标准对话框;带help的对话框,也可以用对话框向导建立需要的对话框。
,
3 应用程序生成
主要包括多窗体、但窗体应用程序生成,可通过ApplicationWizard来建立个性化的应用程序。如下图
技巧
通用知识
快捷菜单的使用
依次为New, Open, Save, Saveall, 打开工程,添加文件(文件已经存在),从工程中移除文件(不删除)
依次为 打开代码/窗口对话框,代码/窗口切换,新建窗体。
代码结构
(紫兰为接口部分,包括use<引用单元>,type<组件、过程、函数,声明?>,var<变量>,use<引用单元>)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
button1.Caption := 'xyz';
end;
end.
窗体属性和事件
a. 窗体透明度设置:Alphablend := true >> AlphablendValue :=k (k在0到255之间)
b. 右上角按钮有无设置:BorderIcons属性(即关闭、最大、最小、问号等按钮)
c. 边框设置:Borderstyle属性,其中为bsNone时无边框,为bsDialog时只有关闭按钮,其他不可改。
d. OnKeyPress事件:窗体激活状态时的键盘事件,参照“键盘的ASC码”应用如下
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin //按Enter键窗体变红
if key = #13 then Form1.Color := clred;
end;
d. OnMouseMove事件:在组件区域内鼠标移动时发生
e. TabOrder属性可以用来设置组件的(初始)焦点
f. 窗体的Onpaint事件,应用见“界面设计技巧”>>窗体背景色渐变
窗体重画
在Form的Canvas上画了很多东西,但窗口移动了一下之后画的东西全没了,怎么解决?
>>重画!将你的过程放在OnPaint事件里!一般在Form的OnPaint事件中写画画的代码。
窗体关闭询问
参见实例047
窗体关闭前会触发ONCloseQuery事件,该事件中的参数canclose是boolean型的
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if application.MessageBox('您将要关闭本窗口!确认是否继续?','询问',MB_YESNO+MB_ICONQUEStION)=ID_NO then
begin
CanClose:=false;
end;
end;
数据类型
1 指针的使用:首先声明指针类型,再声明指针变量
2 变体数据类型Variant和其他数据类型结合使用时自动转换类型
如
V:variant
则:V:= 10; V:= 12.3;V:=’hello’;都是可以的。
Goto 语句的使用
procedure TForm1.Button1Click(Sender: TObject);
label N1;//保留字label声明标号
label N2;
begin
goto N2;
N1: begin
Edit2.Text := Edit1.Text;
edit2.Color := clred;
exit; //程序执行完毕
end;
N2: Edit3.Text := edit1.Text;
goto N1;
end;
使用注意点:语句要在同一过程/函数中使用,不能跨块操作;尽量在同一结构语句中使用;
自定义过程编写
三步:首先在单元文件的Type>Private下定义(在关键字 过程名,如:procedure greetings);再声明过程功能,包括参数类型说明;过程调用
应用如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure greetings; //定义过程
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
greetings; //调用过程
end;
procedure TForm1.greetings; //声明过程(功能)
begin
form1.Color := clRed;
end;
end.
以上为无参过程应用,有参过程如下
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure exchange(var a,b :string);
{ //定义过程,特别注意与声明部分地一行唯一的区别就是没有了“Tform1.”的前缀(声明部分必须有,而定义过程则必须要有参数说明即:(var a,b :string))}
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
x,y:string;
begin
x := edit1.text;
y:= edit2.text;
exchange(x,y); //调用过程
edit3.text := x;
edit4.text := y;
end;
procedure Tform1.exchange(var a,b :string); //声明过程(功能)
var temp : string;
begin
temp := a;
a:= b;
b := temp;
end;
end.
运行界面如下
自定义函数编写
PART1
和过程编写大致一样,注意的地方:必须指定返回值的类型,且函数调用,只能出现在一个表达式中
应用如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
function max(var x,y:real):real; //函数定义,必须指定返回值的类型
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function Tform1.max(var x,y:real):real; //函数声明,必须指定返回值的类型
begin
if x >y then max := x else max := y; //以函数名或本地变量Result作为返回值变量
end;
procedure TForm1.Button1Click(Sender: TObject);
var a,b:real;
begin
a := strtofloat(edit1.Text);
b := strtofloat(edit2.Text);
edit3.Text := floattostr(max(a,b)); //函数调用,只能出现在一个表达式中
end;
end.
运行界面
PART2 函数的返回类型
可以使用Variant类型,
当函数返回类型可以为array时,举例如下:
type
TArrayInt = array of Integer;
function f: TArrayInt;
begin
end;
PART2 用二维动态数组做函数或过程的参数
1.普通的情况
type
TArrAr r= array of array of Integer; //假设是Integer类型的
procdure proc_name(Arr1: TArrArr);
function ...
2. 使用Variant
procdure proc_name(Arr1: Variant);
function ...
Project Options设置
a. 主菜单设置Project>>Options>>Forms页,设置mianform(方法一),也可以在Project代码窗口修改代码,如下设置form2为主窗口:
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1}, //对这部分次序无要求
Unit2 in 'Unit2.pas' {Form2},
Unit3 in 'Unit3.pas' {Form3};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm2, Form2); //Form2首先出现
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm3, Form3);
Application.Run;
end.
动态创建组件
例如创建一个按钮,name为button,父体为panel1,
代码如下:
procedure TForm1.Button1Click(Sender: TObject);
var
Button :tbutton; //组件的类
begin
Button:=Tbutton.create(self);
Button.parent:=panel1; //指定父体
//位置设置
Button.left := 20; //
Button.top := 30;
//Caption属性设置
Button.caption:='OK';
button.Font.Color := CLPURPLE;
//大小设置
button.Width := panel1.Width div 3 ;
button.Height := panel1.Height div 5;
end;
运行界面
几组易混淆的概念
一、Owner和Parent的区别:
Parent属性是指构件的包容器,构件只能在此范围内显示和移动。举例子如下:
(1)在Form1的窗体上,放一个Panel1,并将Panel1拉大,
(2)在Panel1上放一Button1;
(3)在Form1上放一Button2。
现在如果移动Panel1,则Button1随着Panel1移动,这是因为Button1的Parent是Panel1。现在将Button2移到Panel1上,再次移动Panel1,Button2并不跟着移动,这是因为Button2的Parent是Form1。除在窗体设计中,应注意构件的Parent是谁外,在动态创建构件时,也应指出构件的Parent,如在上例中继续操作:
1)Procedure Tform1.Button2click(Sender:Tobjet);
2)Var
3) Button:Tbutton;
4) Begin
5) Button:Tbutton.cerate(self);
6) Button.parent=panel1;
7) Button.lleft=0;
8) Button.top=0;
9) Button.caption:=OK;
10) End;
当按Button2时,将在Panel1上创建一个Button,而如果把第6句改为Button.parent:=self;按Button2时,将在Form1上创建一个Button了。如果将第6句删除,按Button2时,什么都不会发生,这是因为创建方法无法知道应在哪里显示构件。
Owner属性是指构件的所有者,它负责构件的创建和释放。如在上例中,系统默认窗体上所有构件的所有者是窗体,而窗体的所有者是Application。顺便指出,create方法应带有表示构件所有者的参数,如在上例中,构件所有者是窗体,即self。
Parent属性和Owner属性是运行阶段的属性,只能在运行阶段,通过代码设置。
二、Self和Sender的区别:
在事件处理程序参数表中,至少含有一个参数Sender,它代表触发事件处理程序的构件,如在上例中,Sender就指Button2,有了Sender参数,可以使多个构件共用相同的事件处理程序,如下例:
Procedure Tform1.Buttonclick(Sender:Tobject);
Begin
If sender=button1 then
Label1.caption:=′看庭前花开花落
′ Else Label2.caption:=′望天上云卷云舒′
End;
在此例中,Button1,Button2共用了Buttonclick事件处理程序。
Self是指所编的程序范围是在哪一个类中,Delphi中大都在窗体范围内编程,因此,self即指窗体,如果在编写一个类或是一个组件,则self指该类或组件。我们在函数或过程的声明中可看出self是代表哪个组件,即self代表‘.’号之前的组件,如在第一个例子中,self代表Tform1。另外应注意,self而不能用在过程或函数中,如下例用法是错的:
Function a1(B:Integer):Integer;
Begin
……
Button:=tbutton.create(self);……
End;
三、Clientheight和Height,Clientwidth和Width的区别:
对于一般的构件而言,Height就是Clientheight,Width就是Clientwidth,而对于窗体而言,Height是包括标题条在内的高度,而Clientheight是指窗体工作区的高度。同理,Clientwidth是指定窗体工作区的宽度。
从上面陈述可知,理解Ower和Parent,Self和Sender,Clientheight和Height,Clientwidth和Width区别,对于Delphi中正确编程是重要的。
Delphi中动态设置ODBC数据源
在DELPHI数据库应用程序中,我们访问数据库通常有两种方法.一种是通过BDE数据库搜索引擎,即利用DELPHI自带的数据库驱动程序,这种方法的优点是速度快,但应用范围有限,当数据库版本更新时,有可能不能用于操作新的数据库;另一种方法是通过ODBC,这种方法的优点是可以随操作系统(如WINDOWS)提供,作为标准接口能适应多种数据库,缺点是速度慢.在编程时,我们可以根据需要选择其中的一种方法.
ODBC管理程序设置DSN的秘密在注册表中,不信可以到HKEY_LOCAL_MACHINE\Software\ODBC去看看,肯定让你感觉已经成功了一半.
首先来看看系统中已安装的ODBC数据库驱动程序.在HKEY_LOCAL_MACHINE\Software\ODBC\ ODBCInst.INI中,存放着已经安装了的ODBC数据库驱动程序的信息,从这里可以查到已安装的ODBC数据库驱动程序对应的DLL文件等信息.在ODBCInst.INI\ODBC Drivers的各个键值中,键名是驱动程序名称(如Microsoft Access Driv(*.mdb)),键值为“Installed”,表示驱动程序已安装.在ODBCInst.INI\DriverName(DriverName为一个驱动程序名称,如Microsoft Access Driver(*.mdb))中,有驱动程序的详细信息,我们主要从这里获得ODBC驱动程序对应的DLL文件的路径和文件名,即键名Driver的键值,一般为"C:\WINDOWS\SYSTEM\FileName.DLL".
然后来看系统DSN的注册信息,在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI中,存放着系统 DSN的注册信息,我们在ODBC管理面板设置的DSN参数就在这里.
下面来看 唇ㄒ桓鯫DBC系统DSN的步骤,即我们在ODBC管理面板中完成参数设置后,ODBC管理程序是怎么在注册表中注册DSN信息的.以创建一个名称为MyAccess的Ms Access97类型的系统DSN为例,我们指定的参数主要有数据库类型(Microsoft Access Driver(*.mdb))、数据源名称(MyAccess)、数据源描述(我的ACCESS)、数据库路径(C:\Inetpub\wwwroot\Test.mdb),其它参数如用户名称、用户密码、独占、只读、系统数据库、默认目录、缓冲区大小、扫描行数、页超时等采用系统缺省参数.这时,注册系统DSN一般应有以下几个步骤:
1.在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\ODBC Data Sources中增加一个字符串键值,为MyAccess = Microsoft Access Driver(*.mdb),其中分别为数据源名称和数据库类型.这是在注册表中注册一个系统DSN名称.
2.在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI中创建一个子键(SubKey)MyAccess,即创建一个键为HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\MyAccess,然后在其下创建一些键值,详细描述一个系统DSN的配置信息,主要信息有([]中的内容为笔者注释):
DBQ=C:\Inetpub\wwwroot\Test.mdb
[字符串,表示数据库路径]
Description=我的ACCESS
[字符串,表示数据库描述]
Driver=C:\PWIN98\System\odbcjt32.dll
[字符串,表示驱动程序,可见ODBCINST.INI]
DriverId=0x00000019(25)
[数字,表示驱动程序标识,不能改变]
FIL=Ms Access;
[字符串,可能与过滤Filter有关]
SafeTransaction=0x00000000
[数字,可能表示支持事务性操作的个数]
UID=""
[字符串,表示用户名称,此处为空字符串]
3.在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\MyAccess中创建一个子键(SubKey)Engines, 再在其下创建子键(SubKey)Jet,即创建一个键为 HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\MyAccess\Engines\Jet,然后在其下创建一些 键值,详细描述一个系统DSN的数据库引擎配置信息,主要信息有([]中的内容为笔者注释):
ImplicitCommitSync=Yes
[字符串,可能表示是否立即反映数据修改]
MaxBufferSize=0x00000200(512)
[数字,表示缓冲区大小]
PageTimeout=0x00000005(5)
[数字,表示页超时]
Threads=0x00000003(3)
[数字,可能表示支持的最大线程数目]
UserCommitSync=Yes
[字符串,可能表示是否立即将数据修改反映到用户]
以上是建立一个系统DSN的基本信息(其它信息如选项或高级选项等信息也在这里设置,只不过因采用默认信息,注册表里没有列出),我们在程序中按上述步骤操作注册表,同样也能增加一个系统DSN或修改其配置.在下面的例子程序中,将按以上步骤建立一个系统DSN,请注意程序中的注释.
{*******************************************************
在本程序中,将创建一个ODBC系统数据源(DSN),
数据源名称:MyAccess 数据源描述:我的新数据源
数据库类型:ACCESS97
对应数据库:C:\Inetpub\wwwroot\test.mdb
*******************************************************}
{ 注意应在USES语句中包含Registry }
procedure TForm1.Button1Click(Sender: TObject);
var
registerTemp : TRegistry;
bData : array[ 0..0 ] of byte;
begin
registerTemp := TRegistry.Create;
//建立一个Registry实例
with registerTemp do
begin
RootKey:=HKEY_LOCAL_MACHINE;
//设置根键值为HKEY_LOCAL_MACHINE
//找到Software\ODBC\ODBC.INI\ODBC Data Sources
if OpenKey(Software\ODBC\ODBC.INI
\ODBC Data Sources,True) then
begin //注册一个DSN名称
WriteString( MyAccess, Microsoft Access Driver (*.mdb) );
end
else
begin//创建键值失败
memo1.lines.add(增加ODBC数据源失败);
exit;
end;
CloseKey;
//找到或创建Software\ODBC\ODBC.INI
\MyAccess,写入DSN配置信息
if OpenKey(Software\ODBC\ODBC.INI\MyAccess,True) then
begin
WriteString( DBQ, C:\inetpub\wwwroot\test.mdb );//数据库目录
WriteString( Description, 我的新数据源 );//数据源描述
WriteString( Driver, C:\PWIN98\SYSTEM\odbcjt32.dll );//驱动程序DLL文件
WriteInteger( DriverId, 25 );
//驱动程序标识
WriteString( FIL, Ms Access; );
//Filter依据
WriteInteger( SafeTransaction, 0 );
//支持的事务操作数目
WriteString( UID, );//用户名称bData[0] := 0;
WriteBinaryData( Exclusive, bData, 1 );
//非独占方式
WriteBinaryData( ReadOnly, bData, 1 );
//非只读方式
end
else//创建键值失败
begin
memo1.lines.add(增加ODBC数据源失败);
exit;
end;
CloseKey;
//找到或创建Software\ODBC\ODBC.INI
\MyAccess\Engines\Jet
//写入DSN数据库引擎配置信息
if OpenKey(Software\ODBC\ODBC.INI
\MyAccess\Engines\Jet,True) then
begin
WriteString( ImplicitCommitSync, Yes );
WriteInteger( MaxBufferSize, 512 );//缓冲区大小
WriteInteger( PageTimeout, 10 );//页超时
WriteInteger( Threads, 3 );//支持的线程数目
WriteString( UserCommitSync, Yes );
end
else//创建键值失败
begin
memo1.lines.add(增加ODBC数据源失败);
exit;
end;
CloseKey;
memo1.lines.add(增加新ODBC数据源成功);
Free;
end;
end;
以上程序在PWIN98+DELPHI3.0下调试通过.
下面是创建常见数据库类型的DSN需要设置的信息([]为注释内容,除特殊注释外,各参数可见前面说明):
1.Access(Microsoft Access Driver(*.mdb))
DBQ、Description、Driver[odbcjt32.dll]、
DriverID[25]、FIL[Ms Access;]、
SafeTransaction[默认为0]、UID[默认为空]、
Engines\Jet\ImplicitCommitSync[默认为Yes]、
Engines\Jet\MaxBufferSize[默认512]、
Engines\Jet\PageTimeout[默认为512]、
Engines\Jet\Threads[默认为3]、
Engines\Jet\UserCommitSync[默认为Yes]
可选设置:SystemDb[字符串,系统数据库的路径]、
ReadOnly[二进制,是否以只读方式打开,1为是,默认为0]、
Exclusive[二进制,是否以独占方式打开,1为是,默认为0]、PWD[字符串,用户密码]
2.EXCEL(Microsoft Excel Driver(*.xls))
DBQ[Excel97(=path\xxx.xls)、5.0/7.0
(=path\xxx.xls)、4.0(=path)、3.0(=path)]、
Description、Driver[odbcjt32.dll]、
DefaultDir[Excel97($#@60; $#@62;DBQ)、5.0/7.0
($#@60; $#@62;DBQ)、4.0(=DBQ)、3.0(=DBQ)]、
DriverID[790(Excel97)、22(5.0/7.0)、278(4.0)、534(3.0)]、
FIL[Excel5.0;]、ReadOnly、SafeTransaction、UID、
Engines\Excel\ImplicitCommitSync、
Engines\Excel\MaxScanRows[数字,扫描行数,默认为8]、
Engines\Excel\Threads、Engines\Excel\UserCommitSync、
Engines\Excel\FirstRowHasName[二进制,第一行是否是域名,1表示是,默认为1]
注: Excel97和Excel7.0/5.0的DBQ对应一个XLS文件,而Excel4.0和Excel3.0则对应一个目录;DefaultDir对应一个目录,在Excel97和Excel7.0/5.0中是DBQ所对应的路径,而在Excel4.0和Excel3.0下则与DBQ相同;各个版本的DriverID不同.
3.dBase(Microsoft dBase Driver(*.dbf))
DefaultDir[字符串,数据库文件所在目录]、
Description、Driver[odbcjt32.dll]、
DriverID[277(IV)、533(5.0)]、
FIL[dbase III;]、SafeTransaction、UID、
Engines\Xbase\ImplicitCommitSync、
Engines\Xbase\Collating[字符串,排序依据,可为ASCII、International、Norwegian-Danish、
Swedish-Finnish]、
Engines\Xbase\Deleted[二进制,是否不显示被软删除的记录,0表示显示,默认为1]、
Engines\Xbase\PageTimeout[默认为600]、
Engines\Xbase\UserCommitSync、
Engines\Xbase\Threads、Engines\Xbase
\Statistics[二进制,是否用大约的行数,1为是,默认0]
注:(dBaseIV和dBase5.0两个版本的DriverId有不同)
4.Foxpro(Microsoft Foxpro Driver(*.dbf))
DefaultDir[数据库文件所在目录]、
Description、Driver[odbcjt32.dll]、
DriverID[536(2.6)、280(2.5)]、
FIL[Foxpro 2.0;]、SafeTransaction、UID、
Engines\Xbase\Collating[字符串,排序依据,可为ASCII、International]、
Engines\Xbase\Deleted[二进制,是否不显示被软删除的记录,0表示显示,默认为1]、
Engines\Xbase\PageTimeout[默认为600]、
Engines\Xbase\UserCommitSync、
Engines\Xbase\Threads、Engines\Xbase
\Statistics[二进制,是否用大约的行数,1为是,默认0]
注:(Foxpro2.5和Foxpro2.6两个版本的DriverId有不同)
把上面程序做成一个COM或ActiveX控件吧,在很多高级程序设计语言如DELPHI、C++Buider、VB、VC、PB中都能用到的.
一些类
A TCursor
设置它可以使鼠标处于不同的显示状态,如
treeview1.Cursor := crHandPoint; //或 treeview1.Cursor := -21;
即使用的方法为 :控件名.Cursor := TCursor type;可以为字符常数或index,可以参考帮助主题TCursor type
B TRegIniFile
TRegIniFile是Delphi提供的一个标准注册表操作类。该类的WriteString方法可以向注册表中添加或修改一个字符串值。
Tapplication类
TApplication类是用于描述Delphi编制的应用程序的一个类。通过对这个类的灵活应用可以编制许多有特点的程序。下面我们就举几个这方面的例子。
---- 1 检测当前Windows程序是否被激活:
---- Tapplication类有一个属性——Active,这个属性就可以描述当前运行的程序是否被激活,成为Windows的焦点。检测的代码如下:
If Application.Active=False then
ShowMessage(’当前窗口没有被激活’);
---- 2 取得当前程序的名称:
---- Tapplication类的EXEName属性可以返回这个可执行程序的完整文件名(包含路径)。实现的代码如下所示:
---- ShowMessage(Application.ExeName);
---- 3 改变程序极小化时的标题
---- 如果您细心观察可以发现,一些程序的标题和程序的名称并不一致,尤其是一些英文程序,窗体的标题栏比较长,可以容纳比较多的文字,而在最小化时,往往变成了很少的几个字母。这中间起作用的就是Tapplication类的Title属性。这个属性决定了程序最小化时的标题,而窗口中标题栏的标题是由Form的Caption属性来决定的。其代码如下:
Form1.Caption:=’ 窗口的标题’;
Application.Title:=’程序的标题’;
---- 其实我们也可以在在程序设计时指定Tapplication类的Title属性值。操作的方法是在开发环境中拉下Project菜单,选择Options菜单时弹出如图1 (略)的对话框。在这个对话框中的Title栏中填写程序的标题一样也可以达到这种效果。并且因为一般的工程文件都是以英文命名的,所以程序运行过程中弹出的消息框中的标题是英文。但在指定了这个属性之后,这个程序的所有消息窗口的标题都变为Title的值。这就使得程序看起来更加完整。
---- 4 指明程序的主窗口
---- Windows系统中的界面都是窗口,但一般来讲有一个主窗口。Tapplication的MainForm属性(TForm类型数据)就可以返回程序的主窗口。
---- 5 显示消息框
---- 6 控制窗口的尺寸
---- 一般可以用窗口手柄来调整窗口的尺寸,但是也可以用Application的事件来调整。实现的方法是用以下两个过程:
Application.Minimized;
Application.Restore;
---- 前一个过程用来将程序的主窗口最小化,而后一个过程用来将最小化的窗口恢复到原来的尺寸。
---- 7 链接联机帮助文件
---- Application的CurrentHelpFile属性能够指定当前程序所用的联机帮助文件的文件名。这个属性经常与另一个方法联合在一起使用。举例如下:
Application.HelpFile := '联机帮助文件名';
Application.HelpJump('联机帮助文件的主题’)
---- 通过这一命令组合,我们就能使系统弹出一个显示某主题的联机帮助文件。
---- 8 在程序运行时动态地创建窗口
---- 一般情况下,窗口是在设计时加入到工程项目中的,但是有时也需要我们在程序运行时动态地加入窗口,这就要用到Application 的CreateForm过程,举例如下:
Form3:Tform3; //声明窗口类
Application.CreateForm(TForm3, Form3); //创建窗口
---- 9 结束程序
---- 虽然我们可以用关闭主窗口的方法来关闭一个程序,但是更好的办法是用Application的Terminate过程。它能够起到更彻底地关闭程序的效果。
---- 10 Destroy 属性.
---- 虽然Delphi提供了这一属性,但是并不提倡使用它,如果要终结程序就要调用Terminate过程,而Destroy过程一般是用来在程序发生悬挂时来退出程序时才调用,有些类似Windows中的结束任务功能。它不仅能关闭程序实例本身,而且还能释放程序所占用的资源,能够达到将程序彻底清除出系统的目的
异常类
》》文件链接
1. 异常类的基类是TObject ,参考帮助主题Exception
2. 主要属性:Message;主要方法:Create,CreateFmt,CreateFmtHelp,CreateHelp,
3. raise保留字产生异常;
4. 通过try…finally语句和try…except语句嵌套来完成异常处理和资源释放
5. Delphi提供了一个保留字finally,用于实现资源的保护:
{分配资源}
Try
{资源使用情况}
finally
{释放资源}
end;
try…finally…end就形成了一个资源保护块。finally后面的语句是在任何情况下,不论程序是否发生异常,都会执行的。
比如下面一段程序就会造成1K内存资源的丢失。
var
APointer : Pointer ;
AInt , ADiv: Integer ;
begin
ADiv := 0;
GetMem ( APointer , 1024 );
AInt := 10 div ADiv ;
FreeMem ( Apointer , 1024 ); //不可能有执行的机会
end;
由于程序从异常发生点退出从而FreeMem永远没有执行的机会。
如下代码即可确保所分配内存资源的释放:
var
APointer : Pointer ;
AInt , ADiv : Integer;
begin
ADiv := 0;
GetMem ( APointer , 1024 );
try
AInt := 10 div ADiv ;
finally
FreeMem ( Apointer , 1024 );
end;
end;
一般的,程序
如何自动配置BDE
如果是单机数据库(如paradox,Xbase)直接在Install Shield的BDE/IDAPI中设定:
点击specify InstallShield Objects for Delphi 5下的General Options
选择BDE(Borland Database Engine)项,然后点击“settings...”按钮,选full BDE installation,创建一个别名,设定路径,类型。OK
如果是大型数据库(如sql srever):
点击specify InstallShield Objects for Delphi 5下的General Options
选择BDE(Borland Database Engine)和sql links项,然后点击“settings...”按钮,选full BDE installation,创建一个别名,设定路径,类型。OK
记录类型的使用
界面设计和输出结果如下
代码如下
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type Tmyrecord = record //定义用户的数据类型(记录类型)①
a:string;
b:string;
c :integer;
end;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
function f : Tmyrecord; //定义函数 ②
public
{ Public declarations }
end;
var
Form1: TForm1;
re1 : Tmyrecord; //声明记录变量③
implementation
{$R *.dfm}
{ TForm1 }
function TForm1.f: Tmyrecord;
begin //给记录变量赋值(对记录变量操作)④
re1.a := 'string';
re1.b := 'string2';
re1.c := 128;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
f; //调用函数
edit1.Text := re1.a;
edit2.Text := re1.b;
edit3.Text := inttostr(re1.c);
end;
end.
几点说明:
1. ①必须在②前,否则出错,这是因为要先定义类型再引用类型
2. 声明记录变量在Var部分,是先声明记录变量,然后再对记录变量赋值(或操作)
3.完成了③,在④部分操作时,当输入“记录变量名.”后,系统经自动提示记录,如re1中的abc
Ordinal type 的操作
Ordinal types include integer, character, Boolean, enumerated, and subrange types. Several predefined functions operate on ordinal values and type identifiers.
High ,Low,Pred,Succ,Ord ,使用参考Delphi帮助主题“Ordinal types”
使用举例如下
代码如下
procedure TForm1.Button1Click(Sender: TObject);
begin
edit1.Text := pred('b');
edit2.Text := inttostr(succ(5));
edit3.Text:= inttostr(high(Byte));
end;
delphi参数的传递
在Object Pascal中,参数可以分为数值参数(Value)、变量参数(Variable)和常量参数(Constant)3种。默认为数值参数,数值参数总是具有确定的类型。
一般来说,形参列表和实参列表完全匹配是指参数的个数一样,而且顺序排列的数据类型也完全一致。对于一般的函数,如果编译器发现实参的数据类型与形参的数据类型不匹配,会将实参的数据类型进行一次或多次的“提升",比如,将Integer类型转换为Double类型。
2.数值参数
数值参数在运行过程中只改变其形参的值,不改变其实参的值,参数的值不能传递到过程的外面。形参和实参占用不同的内存单元,在过程或函数被调用时,将实参的值复制到形参占用的内存中,相当于C语言函数调用中的传值。因此过程或函数运行结束后,形参和实参的数值是不同的,且实参的值不能发生变化。数值参数必须是一个表达式,且表达式的类型不能是文件类型或包含文件的其他结构类型。
3.变量参数
在有关形参前加上保留字var,这样定义的参数称为变量参数,这时在过程或函数调用中的实际参数必须是变量的引用,在过程或函数的执行期间,这个变量参数就代表了实际参数,改变了变量参数也就改变了实际参数。
4.常量参数
如果当过程或函数执行时要求不改变形参的值,最好的办法就是使用常量参数。在定义形式参数表的有关参数前加上保留字const,就可以定义常量参数。
常量参数可以像局部只读变量一样使用,其初值来自过程或函数调用时的实参,实参必须是一个表达式,且表达式的类型不能是文件类型或包含文件类型的其他结构类型。
不允许在过程或函数中给常量参数赋值,并且常量参数不能作为实参传递给另外一个过程或函数。
5.参数默认值
……
6.参数传递的顺序 .
……
程序的驻留和内存释放\动态创建窗体
1. 自动创建窗体。正常创建的窗体,在project/options的左边Auto-Create forms栏中,
工程启动时窗体自动创建且被送往系统内存。但会造成内存的开销。
2. 调用窗体。指的是调用右边的Available Forms,调用代码示例如下
procedure TForm1.Button1Click(Sender: TObject);
var f : pointer; //定义指针变量
begin
try
getmem(f,1024000); //分配内存变量
if form2 = nil then form2 := Tform2.Create(self); {若Form2为Available Form(窗体属性为Nil)时创建窗体}
form2.show;
finally
FREEmem(f,1024000); //释放内存变量
end;
end;
3. 窗体的释放
示例:释放窗体Form1
方法一 Form1.Release或Form1.Free;
方法二 在Form1窗体添加Onclose事件,代码中写入action := cafree;
方法三 FreeAndNil(Form1); //释放,并且把窗体转化为Available Form
>>两步搞定动态创建窗体:1.project文件中删除代码;2.在所有的show方法前加上窗体名 := T窗体名.Create(nil);
程序开机自动运行
查看实例234
在系统启动时自动运行程序最常用的方法就是在系统注册表中“Hkey_local_machine\software\microsoft\windows\currentversion\run”键下添加Windows启动后自动启动的程序,利用TRegIniFile类的WriteString方法写入或修改注册表的字符串值。
procedure TForm1.zdyx(a, b: string; c: boolean);
var
d: string;
e: TReginiFile;
begin
if c then
d := 'once'
else
d:= '';
e := TRegIniFile.Create('');
e.RootKey := HKEY_LOCAL_MACHINE;
e.WriteString('software\microsoft\windows\currentversion\run'+d +#0,a,b); //写入字//符串值到注册表
e.Free ;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
self.zdyx('ZDYX',application.ExeName,false);
end;
注册表操作
*****************实例荟萃
参见实例247
该实例实现了创建键reg,并读取某键下的数据100100,010101,如下图:
参见实例248
该实例首先创建键reg,然后在键值项password和user中写入键值31,123;
校对按钮校对输入框内的用户名和密码是否和注册表的用户名和密码一致。
读写键值注意windows的版本!
参见实例251,本实例完成桌面图标的隐藏和显示
(桌面也是一个窗口,该窗口的类名为ProgMan,用Findwindow函数返回窗口句柄,然后再调用ShowWindow函数使它隐藏或显示)
procedure TForm1.Button1Click(Sender: TObject);
var
deskhandle: THandle;
begin
deskhandle:= FindWindow('ProgMan',nil);
ShowWindow(deskhandle,SW_HIDE); // 其他窗口显示方式参见
end;
procedure TForm1.Button2Click(Sender: TObject);
var
deskhandle: THandle;
begin
deskhandle:= FindWindow('ProgMan',nil);
ShowWindow(deskhandle,SW_SHOW);
end;
参见实例253 本实例实现禁用、启用注册表
procedure TForm1.Button1Click(Sender: TObject);
var
myr:TRegistry;
begin
myr:=Tregistry.Create;
myr.RootKey:=HKEY_CURRENT_USER;
myr.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer',true); //路径不一定要这个才行
if RadioGroup1.ItemIndex=0 then
begin
myr.WriteInteger('disallowrun',0); //创建键值项,把数据写为零?也就是默认(可以运行),或者说
//对windows不起作用?
MessageDlg('允许使用注册表设置完成', mtInformation,[mbOk], 0 );
end
else
begin
myr.WriteInteger('disallowrun',1); myr.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\disallowrun',true);
myr.WriteString('1','regedit.exe'); // disallowrun键值下的禁用regedit.exe,(也可以是其他的程序?)
MessageDlg('不允许使用注册表设置完成', mtInformation,[mbOk], 0 );
end;
end;
参见实例256,修改IE浏览器默认主页
在“HKEY function TFrmStarPage.ShowStartPage:string; var reg:TRegistry; begin //返回默认主页 reg:=TRegistry.Create; reg.RootKey:=HKEY_CURRENT_USER; reg.OpenKey('SoftWare\Microsoft\Internet Explorer\Main',true); result:=reg.ReadString('Start Page'); Reg.CloseKey; reg.Free; end; procedure TFrmStarPage.SetStartPage(Const Page:string); var reg:TRegistry; begin //设置默认主页 reg:=TRegistry.Create; reg.RootKey:=HKEY_CURRENT_USER; reg.OpenKey('SoftWare\Microsoft\Internet Explorer\Main',true); reg.WriteString('Start Page',page); //Page为网址字符串 Reg.CloseKey; reg.Free; end; procedure TFrmStarPage.FormShow(Sender: TObject); begin EdOldPage.Text:=ShowStartPage; end; procedure TFrmStarPage.BtnSetClick(Sender: TObject); begin if trim(EDStarPage.Text) = '' then begin SetStartPage('about:blank'); end else SetStartPage(EDStarPage.Text); end; procedure TFrmStarPage.BtnCloseClick(Sender: TObject); begin Close; end; ********************************************//如下为技术支持 提供了Tregistry类来操作注册表,操作的第一步是在Uses中加入Registry单元,否则出错。 一、创建和释放TRegistry对象 ◇ delphi的tregistry注册表类方法详解 ◇ 应用之一:让自己的程序随WIN95/98/NT的启动而运行 1. 首先在程序文件系统中建立一个INI文件(可以拷贝后修改) 2. 在程序中Use IniFiles文件; 3. 声明一个TIniFile对象iniinfo :TIniFile;; 4. 打开INI文件; 5. 进行读写操作。 6. 释放对象 代码如下 Uses IniFiles; …… procedure TFrmInfo.FormShow(Sender: TObject); var iniinfo:TIniFile; begin iniInfo:=TInIFile.Create(dir+'\MyInfo.INI'); //打开INI文件 try //**INI读文件 EdName.Text:=iniInfo.ReadString('PersionInfo','Name','赵智勇'); EdBornDate.Text:=iniInfo.ReadString('PersionInfo','BornDate','1982-03-21'); EdDo.Text:=iniInfo.ReadString('PersionInfo','Work','Software Developer'); EdPhone.Text:=iniInfo.ReadString('PersionInfo','Phone','13194368966'); EDHome.Text:=iniInfo.ReadString('PersionInfo','Home','吉林省长春市'); Finally freeAndNil(IniInfo); //释放对象 end; 步骤:声明一个Text类型的文件指针>>AssignFile方法关联文件>>打开文件>>读写文件>>关闭 应用如下:已建文本文件wenben.txt,有如下程序 procedure TForm1.Button3Click(Sender: TObject); var f: textfile; //声明文件指针 i:integer; begin assignfile(f,'wenben.txt'); //文件指针和外部文件关联 //用Readln方法读取一行文本,Writeln方法向文本中写入一行 rewrite(f); //打开文件(三种打开方式:Append、Reset和Rewrite) for i:=1 to 50 do writeln(f,i); //写入文本 //用Readln方法读取一行文本,Writeln方法向文本中写入一行 closefile(f); end; 值得注意到是,有函数eoln(f)判断是否已到行末;可以用memo1.Lines.LoadFromFile('wenben.txt')和memo1.Lines.savetoFile('wenben.txt')等方法读写文本文件数据 读写程序实例: procedure TForm1.Button1Click(Sender: TObject); var f:file of integer; //声明文件指针(注意和文本文件的区别) i:integer; begin assignfile(f,'erjinzhi.txt'); rewrite(f); //打开文件 for i:=1 to 50 do write(f,i); //循环方法写数据,注意是函数write(); closefile(f); end; procedure TForm1.Button2Click(Sender: TObject); var f:file of integer; i:integer; begin assignfile(f,'erjinzhi.txt'); reset(f); while not Eof(f) do begin //Eof(f)函数判断是否到文件末尾 Eof(f) Read (f,i); //循环读数据 Memo1.Lines.Add(inttostr(i)); end; closefile(f); end; http://blog.csdn.net/hongjiujing/archive/2007/09/07/1775635.aspx function InputBox(const ACaption, APrompt, ADefault: string): string; //返回输入字符 function InputBox(const ACaption, APrompt, ADefault: WideString ): WideString; overload; function InputBox(const ACaption, APrompt: WideString ; ADefault: Double; Min: Double = Low(Integer); Max: Double = High(Integer); Decimals: Integer = 1): Double; overload; function InputBox(const ACaption, APrompt: WideString; ADefault: Integer; Min: Integer = Low(Integer); Max: Integer = High(Integer); Increment: Integer = 1): Integer; overload; >>>>>>> Call InputBox to bring up an input dialog box ready for the user to enter a string, double, or integer in its edit box. ACaption is the caption of the dialog box. APrompt is the text that prompts the user to enter input in the edit box. ADefault is the value that appears in the edit box when the dialog box first appears. AMin is the minimum value the user can enter into the edit box. AMax is the maximum value the user can enter into the edit box. 一般随机数生成器的基本原理是:首先初始化一个随机种子,其初始值可以是任意的整数;在每次获取随机数时,以随机种子为基础进行某种特殊的运算,获得一个随机数并返回之,然后再对随机种子进行某种运算,改变随机种子的值。这样,就可以生成许多比较随机的数, 但同一个初始值的随机种子将会生成完全相同的随机数列。 Pascal的System单元提供了两个与随机数有关的子程序: Randomize和Random。 Randomize过程用于初始化随机种子,其初始值取决于当前的系统时钟。 Random函数用于获取随机数 它有两种调用形式: Random,返回一个0到1之间(不包括1)的随机实数;{不用random(1)} Random(N),返回0至N之间(不包括N)的随机整数,N为Word类型整数。 另外,System单元中随机种子变量的标识符为RandSeed,你也可以手动修改它。 随机数在信息学奥林匹克中可用于随机化搜索、穷举等算法,以优化其性能,也 可用于在快速排序中选择关键数,以使其快速排序算法的最坏情况没有固定的相 应数列。如果你希望使用了随机数的程序对同一个输入数据能有恒定的输出结果, 可以设置RandSeed为一个定值。 >>FileExists, RenameFile, FileCreate, FileWrite, FileClose, ExtractFileName 参见delphi帮助主题和链接文件 界面设计如下 代码如下 procedure TForm1.Button1Click(Sender: TObject); begin //创建 Test文件夹 CreateDirectory('E:\Test',nil); end; procedure TForm1.Button3Click(Sender: TObject); begin //在Test文件夹下创建文件名为Windows的Txt文件 FileCreate('E:\Test\windows.txt'); end; procedure TForm1.Button5Click(Sender: TObject); begin //Windows的Txt文件 更名为 windows22 renameFile('E:\Test\windows.txt','E:\Test\windows22.txt'); end; procedure TForm1.Button4Click(Sender: TObject); var FileHandle:thandle; begin FileHandle := FileCreate('E:\Test\vista.txt'); //获得文件的句柄 filewrite(FileHandle,'adsfdfdfdfasdfd',sizeof('adsfdfdfdfasdfd')); {往文件中写数据 } FileClose(FileHandle); {关闭文件(文件在应用程序使用阶段Windows不能正常打开,所以操作完后关闭) } end; procedure TForm1.Button6Click(Sender: TObject); begin DeleteFile('E:\Test\vista.txt'); //删除文件 end; 1********* begin 2********* 首先定义一个全局变量AppPath;然后用函数GetDir(0,AppPath);取得程序的绝对路径 比如程序在桌面的文件夹267中运行,取得的路径为:“C:\...\桌面\267” 链接相关 查看实例230 调用word: 首先use ComObj 然后添加如下程序: procedure TForm1.Button1Click(Sender: TObject); var word : olevariant; begin word := createoleobject('word.application'); word.visible := true; word.documents.add; end; 类似其他组件调用参见实例018 创建Dll: 步骤: 1. 在file/new/other中的new页中打开dll wizard;自动创建一个工程文件,以library关键字开头; 2. 以适当文件名保存; 3. 新建Unit单元,输入过程和函数,例如: unit FirstDll; interface Function Add10(number:integer):integer;stdcall; //声明, implementation Function Add10(number:integer):integer; begin result := number + 10; // 函数语句 end; end. 4. 工程文件中建立Exports 子句 library MyFirstDll; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses SysUtils, Classes, FirstDll in 'FirstDll.pas'; exports ADD10; //建立Exports 子句 {$R *.res} begin //添加DLL初始化代码 end. 5. 编译生成Dll文件(Project>>Compile……) 6. 在调用程序(主程序)中的单元文件中的Interface部分进行声明,调用,如: unit Unit1; interface uses ShareMem,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, XPMan, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; XPManifest1: TXPManifest; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; Function Add10(number:integer):integer;stdcall;external 'MyFirstDll.dll'; //声明,大小写敏感 var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var temp :integer; begin try temp := Strtoint(Edit1.text); Edit1.text := inttostr(Add10(temp)); //调用函数 except Showmessage('Error!') end; end; end. 查看实例502 步骤: 7. 在file/new/other中的new页中打开dll wizard; 8. 在代码窗口中的单元代码窗口定义类; 9. 在工程文件中编写程序,用以提供用户访问类的接口。 Ping.exe是windows系统中一个测试网络连接和传输性能的工具,ping使用了ICMP作为传输协议,在windows上icmp.dll库文件中包含了一系列的ICMP函数 参见实例455 参见实例456 实例说明:使用windows中的ActiveX控件的MSComm。(Delphi7以前的版本) COM即Comeponent Object Model(组件对象模型), MTS 即微软事务服务器; 进程内服务器:用Dll实现COM对象; 进程外服务器:在应用程序中实现COM对象或当Dll在另外的计算机(DCOM)或宿主环境(MTS)中执行时。 含有COM对象的库在Delphi中称为ActiveX库,生成方法:File/New/ActiveX页.. ActiveX library. 1. 建立进程内COM服务器 生成ActiveX库后的完整源代码如下: library Project2; uses ComServ; exports DllGetClassObject, //用于从外部访问类库 DllCanUnloadNow, // 检查服务器的全部对象是否被删除从而可以从内存中卸载 DllRegisterServer, // DllUnregisterServer; // {$R *.RES} begin end. 接下来添加COM对象 填写类名,点击list选择Windows注册表中已有的接口.. 2. 使用类型库编辑器 3. 创建COM+对象 步骤: 1. 在程序中声明一个全局函数,该函数类型和动态库中定义的函数类型一致,示例中都是“TDllClass”。 2. 使用关键字external导入动态库; 实例程序如下: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, jpeg, ExtCtrls; type TDllClass = Class (TObject) published Public procedure Showinfo;virtual;abstract; end; TForm1 = class(TForm) Button1: TButton; Image1: TImage; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; Function CreateObj: TDllClass; //声明一个全局函数 external 'project1.dll'; //使用关键字external导入动态库 implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var temp: TDllClass; begin temp := CreateObj; temp.Showinfo; temp.Free; end; end. >>参见资料 程序界面如下: 程序由一个主单元Unit1、主窗口Form1和两线程单元Unit2和Unit3组成,在Unit1代码如下 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Edit2: TEdit; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} uses unit2,unit3; //引用线程单元,第一步 var thread1:SS; //定义线程,第二步 thread2:TT; procedure TForm1.FormCreate(Sender: TObject); //初始化时创建线程,第三步 begin thread1 := SS.Create(true); thread2 := TT.create; end; procedure TForm1.Button1Click(Sender: TObject); //唤醒线程,第四步 begin thread1.Resume; thread2.Resume; end; end. --------------------------------------------------------- Unit2的代码如下(Unit3类似) unit Unit2; interface uses //注意添加相关部分,此一; Classes,Unit1,Windows, Messages, SysUtils, Variants, Graphics, Controls, Forms, Dialogs, StdCtrls; type SS = class(TThread) private { Private declarations } protected procedure Execute; override; end; implementation { Important: Methods and properties of objects in visual components can only be used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure SS.UpdateCaption; begin Form1.Caption := 'Updated in a thread'; end; } { SS } procedure SS.Execute; //添加线程唤醒是的执行程序,此二; var i:integer; begin { Place thread code here } for i := 0 to 1000 do form1.Edit1.Text := inttostr(i); end; end. 选择View|Debug Windows|Breakpoints菜单打开断点列表窗口。 实际上在Delphi中有一个TScreen元件,与TApplication元件一样,TScreen元件也是在Forms单元中声明的, Delphi已经在Forms单元中声明了TScreen元件的实例,名叫Screen,因此在程序中只需直接调用就可以了,其中Screen.Height是屏幕的高度,Screen.Width是屏幕的宽度(以像素为单位),从这两个值我们就可以很容易地知道屏幕的分辨率了。 messagebeep(0); 例如让电脑连续发出“嘣嘣”声 procedure TForm1.Button1Click(Sender: TObject); var i :integer; begin for i := 1 to 1000 do begin messagebeep(0); //发声 sleep(500); //系统延时0.5秒 end; end; 首先在窗口中添加控件,然后添加控件的MouseDown事件,以button控件举例如下: procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Const //定义常量 SC_DragMove = $F012; { a magic number } begin ReleaseCapture; //从当前线程中的窗口释放鼠标捕获 button1.perform(WM_SysCommand, SC_DragMove, 0); {注:function Perform(Msg: Cardinal; WParam, LParam: Longint): Longint; Responds as if the control received a specified Windows message. // Cardinal wei 32位无符号数} end; 设计窗口如下,并把它们相互连接。(数据表为delphi6.0中的……DBDemos/customers.db) 编写代码如下: procedure TForm1.FormCreate(Sender: TObject); var i : integer; begin for i := 0 to table1.fieldcount-1 do dblistbox1.Items.Add(table1.Fields[i].fieldname); end; 执行结果如下 Windows提供了API函数ExitWindowsEx,通过传递不同的参数,会议不同的方式退出Windows,代码如下: procedure TForm1.Button1Click(Sender: TObject); var st :SYSTEMTIME; hToken :THANDLE; tkp:TOKEN_PRIVILEGES; rr :DWORD; begin OPENPROCESSTOKEN(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,hTOKEN); LookupPrivilegeValue(nil,'SeShutDownPrivilege',tkp.privileges[0].luid); //设定权限为1 tkp.privilegeCount := 1; tkp.privileges[0].Attributes := SE_PRIVILEGE_ENABLED; //得到权限 AdjustTokenPrivileges(hToken,FALSE,tkp,0,nil,rr); //关闭计算机 // ExitWindows(0,0); //关闭方式1 // ExitWindowsEx(EWX_LOGOFF,0); //关闭方式2 关闭所有进程后用户推出*(进入登录界面) // ExitWindowsEx(EWX_FORCE,0); //关闭方式3 强制终止进程 // ExitWindowsEx(EWX_POWEROFF,0); //关闭方式4 关闭系统关闭电源 ExitWindowsEx(EWX_REBOOT,0); //关闭方式5 重新启动计算机* (重启动) // ExitWindowsEx(EWX_SHUTDOWN,0); //关闭方式6 关闭系统 * (不重新启动) end; 关键是调用API函数中的SetWindowPos函数,使用该函数可以控制窗体的显示状态,函数原型是: 应用实例 界面 代码如下 procedure TForm1.Button1Click(Sender: TObject); begin //显示在最前 SetWindowPos(Form1.Handle,HWND_TOPMOST, Form1.Left ,Form1.top,Form1.width,Form1.height,0); end; procedure TForm1.Button2Click(Sender: TObject); begin //回复正常 SetWindowPos(Form1.Handle,HWND_NOTOPMOST, Form1.Left ,Form1.top,Form1.width,Form1.height,0); end; 如果要窗体始终保持在最上方,设置窗体的FormStyle属性为fsStayOnTop 1. Xpmanifest: 在一个工程中添加一个就可显示WindowsXP效果; 2. ActionManager,ActionMainMenuBar,ActionToolBar这三个控件的具体使用:ActionManager控件可以方便的实现动态菜单管理,不管在设计阶段还是运行阶段都可以任意添加、删除、脱放菜单。 ActionManager像个容器,可以存放ActionToolBar和ActionMainMenuBar。 ActionToolBar和ActionMainMenuBar 都可以定制背景,这使得我们在设计界面时更灵活,达到更生动的效果。有一点需要注意,背景图片必须是BMP格式,否则运行时是看不见背景的。 3. Additional页面中的 控件,即ActionManager,ActionMainMenuBar, ActionToolBar,…CustomizeDlg.有关使用方法 这三个控件是用来完全替换BCB以前版本中的action list的。 附注:可以在ActionMainMenuBar,ActionToolBar内修改菜单项的Caption属性,也可以双击添加ONClick事件代码。 步骤:1新建一闪屏图象窗体,设置好属性,载如图片 2.打开ProjectOptions的Forms页,把闪屏图象窗体移入Available forms中,如图。 3.在project代码口中修改代码如下 program Project1; uses Forms, Windows, //添加windows组件 Unit1 in 'C:\Documents and Settings\Administrator\桌面\test\Unit1.pas' {Form1}, Unit2 in 'C:\Documents and Settings\Administrator\桌面\test\Unit2.pas' {Form2}, Unit3 in 'Unit3.pas' {Form3}; {$R *.res} begin Application.Initialize; form3 := Tform3.Create(application); //程序段1 form3.Show; form3.Update; sleep(5000); //延时程序,控制显图时间前提是在Uses中/添加windows组件。 Application.CreateForm(TForm1, Form1); form3.Close; //程序段2 form3.Free; Application.CreateForm(TForm2, Form2); Application.Run; end. 主窗体:Form1中加Panel1, Panel1的属性DockSite设为True,DragKind设为dkDrag, DragMode设为dmmanual 子窗体:Form2的属性DragKind设为dkDock, DragMode设为dmAuromatic 在事件代码中加: Form2.Show; Form2.ManualDock(Panel1, nil, alclient); // Panel1为窗口“宿主” form2.FormStyle:=fsStayOnTop; 在窗体的加入Timer控件,写入一行代码 procedure TForm1.Timer1Timer(Sender: TObject); begin Flashwindow(self.Handle,true); // API函数实现窗体闪烁 end; 活动控件有游动控件、颤动控件,他们都用始终控件控制,设置时钟空间适当的interval属性,然后在时钟控件里写代码,改变控件的位置、大小、颜色、和Visible 等属性,譬如对于图像控件,制作颤动控件,编写如下代码: procedure TForm1.Timer1Timer(Sender: TObject); begin if image1.Visible = false then image1.Visible := true else if image1.Visible = true then image1.Visible := false; end; 为了建立完美与灵活的、可以适应窗前当前大小的用户界面,Delphi允许使用控件的Anchors属性来确定控件和窗体的像是对位置。 参见实例 对窗体增加Onpaint事件,代码如下: procedure TForm1.FormPaint(Sender: TObject); var i:word; y,dy:real; begin dy := clientheight/130; //调整数字可以调整颜色变化跨度 y :=0; for i:= 255 downto 0 do begin form1.Canvas.Brush.Color := $000000 + i*$10000;;//修改数字以更改颜色组合 form1.Canvas.FillRect(rect(0,round(y),clientwidth,round(y+dy))); y := y + dy ; end; end; 下面在窗体中旋转文字,文字的内容,属性在程序中设置: 代码如下: procedure TForm1.Button1Click(Sender: TObject); var lf :tlogfont; tf :tfont; begin with form1.Canvas do //form1为文字所在窗口 begin font.Name:= '华文彩云'; //字体设置 font.Size := 30; font.Color := clred; tf := tfont.Create; tf.Assign(font); getobject(tf.Handle,sizeof(lf),@lf); lf.lfEscapement := 450; //旋文字转角度,单位1/10度 lf.lfOrientation := 450; tf.Handle := createfontindirect(lf); font.Assign(tf); tf.Free; //输出文字,改变数字设置文字在窗体中的位置 textout(400, height div 30 ,'Delphi World!'); end; end; 对象以图片为例(也可以为Form等),界面设计及运行后的界面 代码如下 procedure TForm1.Button1Click(Sender: TObject); begin with image1 do {对象为image1} begin //指定画笔颜色 canvas.Brush.Color := clred ; //画笔类型,常见类型有 {bsSolid, bsClear, bsHorizontal, bsVertical, bsFDiagonal, bsBDiagonal, bsCross, or bsDiagCross. 参照delphi帮助主题 brush style} canvas.Brush.Style := bsBDiagonal; //绘图区域类型和区域大小,其他的区域类型有Ellipse,RoundRect等 canvas.Rectangle(0,0,3*image1.Width ,3*image1.Height); end; 链接 参见实例018 应用步骤:1.添加TTreeView控件,右击之,ItemEdit中编辑树形。2.添加TTreeView控件的Dbclick时间,运用if treeview1.Selected.Text = '树叶名 ' then begin {} End; 示例如: 代码如下: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls; type TForm1 = class(TForm) TreeView1: TTreeView; procedure TreeView1DblClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.TreeView1DblClick(Sender: TObject); begin if treeview1.Selected.Text = '数据导出' then showmessage('数据导出!'); if treeview1.Selected.Text = '数据查询' then showmessage('数据查询!'); end; end. 对于窗体Form1: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure WMNCHitTest(var Msg: TWMNCHITTEST); message WM_NCHITTEST; //第一项 private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.WMNCHitTest(var Msg: TWMNCHITTEST); begin inherited; if msg.Result=HTCaption then Msg.Result := HTCLIENT;/取消鼠标左击标题栏的消息 end; end. 参见实例034 主要新概念:TAnimate及其属性FileName,Active的使用。 界面如下: 主要代码: unit main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, OleCtrls, SHDocVw, StdCtrls, ExtCtrls, jpeg, ComCtrls, shellapi; type TForm1 = class(TForm) Image1: TImage; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; Label7: TLabel; Label8: TLabel; Label9: TLabel; Label10: TLabel; Label11: TLabel; Animate1: TAnimate; Animate3: TAnimate; Animate2: TAnimate; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Label8Click(Sender: TObject); begin showmessage('打开窗体'); end; //添加动画 procedure TForm1.FormCreate(Sender: TObject); begin Animate1.FileName := ExtractFilePath(Application.ExeName)+ 'avi\zybiao.avi'; Animate1.Active := True; Animate2.FileName := ExtractFilePath(Application.ExeName)+ 'avi\Electron.avi'; Animate3.FileName := ExtractFilePath(Application.ExeName)+ 'avi\gd.avi'; Animate2.Active := True; Animate3.Active := True; end; ………… end. 参见实例029 另外获取窗体设备场景函数:GetWindowDC 查看实例001 技术要点:API函数GetSystemMenu,AppendMenu 查看实例2 自设计代码如下 procedure TForm1.N2Click(Sender: TObject); var QQ :tmenuItem; N_still,NDyn_max:integer; begin QQ := TmenuItem.Create(nil); if OpenDialog1.Execute then begin QQ.Caption:=OpenDialog1.FileName; /动态插入菜单 MainMenu1.Items.Items[0].Insert(2,QQ); //2为菜单插入位index //限制动态菜单最大项目数,N_still为静态设计菜单数,NDyn_max为动态最大项目数 N_still := 3; NDyn_max := 4; if (Mainmenu1.Items.Items[0].count- N_still > NDyn_max)then MainMenu1.Items.Items[0].Delete(Mainmenu1.Items.Items[0].count-3); end; end; 查看实例007 主要步骤:1启动载入图片;2工具栏AdvancedCustomDraw事件绘制图片;3工具栏Resize事件保证背景图片正确显示(注意背景图片的含义) 界面如下: 代码如下 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, ToolWin; type TForm1 = class(TForm) ToolBar1: TToolBar; ToolButton1: TToolButton; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure ToolBar1AdvancedCustomDraw(Sender: TToolBar; const ARect: TRect; Stage: TCustomDrawStage; var DefaultDraw: Boolean); procedure ToolBar1Resize(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; bmp :tbitmap; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin //启动载入图片 bmp := tbitmap.Create; bmp.LoadFromFile('E:\资料\图标库\IconLib\BmpLib\BePC\checkbox.bmp'); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin bmp.Free; end; procedure TForm1.ToolBar1AdvancedCustomDraw(Sender: TToolBar; const ARect: TRect; Stage: TCustomDrawStage; var DefaultDraw: Boolean); begin sender.Canvas.StretchDraw(arect,bmp); end; procedure TForm1.ToolBar1Resize(Sender: TObject); begin toolbar1.Repaint; //重画 end; end. 查看实例013 设计思路: 1. 拖放一个panel做容器,若干个Panel作按钮(或作为Button的容器,align属性设置为altop),和一个TlistView控件(align属性设置为alclient)用来显示按钮下的项目; 2. 拖入ImageList控件并载入图片,设置TlistView的largeimages属性为ImageList控件; 3. 写按钮的单击事件,包括按钮的布置和添加项目。实例如下 界面设计 Panel2 的代码如下: procedure TForm1.Panel2Click(Sender: TObject); var newitem:Tlistitem; //变量类型 begin //按钮布置 if panel2.Align = altop then begin //为真则把其余的按钮Align属性设为Albottom panel3.Align := albottom; panel4.Align := albottom; panel5.Align := albottom; end else //为假时 panel2.Align := altop; listview1.Clear; //添加项目1 newitem:=listview1.Items.Add; newitem.Caption:='[项目一]'; //项目文字 newitem.ImageIndex:=1; //图标在imagelist中的索引号 //添加项目2 newitem:=listview1.Items.Add; newitem.Caption:='[项目1-1]'; newitem.ImageIndex:=5; end; 关于本实例,还有两方面的学习 A. 渐变工具栏的制作 ---Photoshop做图片,载入iamge控件,工具栏作为image控件的容器 B. Speedbutton的透明性设置;Speedbutton的载入图片以及和文字的布局关系 ---Transparent属性设True,Flat属性设为True; ---Glyph属性载入图片,layout属性设置布局方向; 查看实例014 套接字(Socket)可以看成在两个程序进行通讯连接中的一个端点,一个程序将一段信息写入Socket中,该Socket将这段信息发送给另外一个Socket中,使这段信息能传送到其他程序中。 套接字是网络通信接口。随着UNIX操作系统的广泛使用,Socket亦当之无愧的成为了最流行的网络通信程序接口之一。1992年推出了WindowsSocketsV1.0版,次年发表了其2.0版,IBM发行的TCP/IPV2.1forDOS就是其代表,它还提供了WindowsSockets的应用程序接口(API)。Microsoft的WindowsSocketsAPI是Windows下的网络应用程序接口,为了适用于Windows下的消息机制和异步的I/O选择操作,WindowsSocketsAPI在功能上扩充了将近20个函数,其中扩充的部分均冠以前缀WSA(WindowsSocketsAsynchronous),如WSAStartup、WSAClean等,充分体现了Widnows的优越性。 此外,WindowsSocketsAPI有16位版和32位版两种,16位版是单进程的,32位版则提供了多线程下的安全保护。 本文将浅解Windows下的Sockets编程的机理,旨在抛砖引玉。一并说明WindowsSockets编程的重要性! 一、WindowsSockets简介 套接字存在于其特定的通信域(即地址族)中,只有隶属于同一地址族的套接字才能建立对话,WindowsSocketsV1.0目前只支持网际域(AF_INET),所有使用网际协议簇的进程均适用于该域。一般情况下除非通信协议支持,只有相同类型的套接字方能相互传递数据,WindowsSocketsV1.1版主要支持两种类型的套接字:流式套接字和数据报套接字,还有一种是原始套接字,但为保证网络应用程序的兼容性,一般不鼓励使用原始套接字。 因为WindowsSockets主要是面向C/S体系结构的,即客户向服务器发出请求,服务器只有在接收到请求后才能提供相应服务。双方在建立对话前,服务进程和接受服务的进程(客户)必须首先建立起各自用于网间进程通信的半相关,即一个三元组(协议,本地地址,本地端口),但只有双方独立的半相关还不能建立起沟通。一个完整的网络通信进程必须通过由两个独立进程组成的一个完整的全相关唯一确定方能得已实现,而且,只有两个性质相同的半相关才能建立一个完整的全相关五元组——(协议,本地地址,本地端口,远地地址,远地端口),由此方能建立起一个网间进程通信的实例。 让我们由C/S模式的主动请求方式来解释用WindowsSockets建立网络进程间对话的过程。 首先启动服务器方,以提供相应服务: (1)打开一个通信通道并通知网络:本机将在某一公认的端口上等待客户(Client)请求; (2)服务器进入阻塞等待状态,等待客户请求的到来; (3)当服务器接收到一个客户的连接请求时,激活一个新的进程用于处理客户请求并建立C/S对话,服务完成后,关闭此新进程与户的通信链路,并将其终止; (4)返回第(2)步,等待另一客户请求; (5)关闭服务器。 客户端进程: (1)指定想与之建立连接的服务器相应服务的保留端口号; (2)向服务器发送CONNECT请求并等待服务器的应答; (3)接收到服务器建立连接的响应后接受服务器相应服务; (4)服务请求结束后关闭通信通道并终止。 由此可见,用WindowsSockets建立的面向连接的无重复套接字系统的过程实现图解如下: 流式套接字首先由客户与正在某一端口监听的服务器建立起连接后方能进行数据传送,并且是双工的。与此不同,用数据报协议实现的网络进程间通信过程如下: WindowsSockets编程还可应用于远程进程调用(RPC),它使得用户进程可调用远端的进程,为远程控制和分布式管理带来了方便。在对等网络中应用也极其广泛,如Windows的网上白板(Chat)和红心大战均是通过WindowsSockets建立的网络连接而进行进程间通信的。现今的许多网络游戏则是WindowsSockets的直接利用。可以说WindowsSockets是网络游戏 二、WindowsSockets编程初探 在TCP应用中,为了建立一个网络连接实例(Instance)的服务器端,只需设置本地服务断口号,然后服务器调用方法Listen进入阻塞状态等待来自客户的连接请求。与此对应的客户端不但要将Winsock的属性RemoteHost置为服务器的名称(IP地址或网络代号),还应设置服务器所监听的相应服务的端口号(RemotePort),如FTP服务在21号端口,HTTP在81号端口等。然后调用方法Winsock.Connect向服务器发出请求。服务器接收到客户请求时,事件ConnectionRequest将被触发。如服务器愿意提供服务则可调用Accept方法接受连接。 一旦连接建立,两端均可使用SendData或GetData进行数据的发送或接收。事件DataArrival将在另一端数据准备就绪时被触发。 UDP协议的实现与TCP不同的是,调用Sockets的两端无需建立连接便可进行数据的传输。因此,一个UDP应用可以同时担任服务器或客户的角色。 三、综述 1、WSAStartup函数 2、socket函数 3、inet_addr函数 4、gethostbyname函数 5、Bind函数 6、connect函数 7、select函数 8、recv函数 9、sendto函数 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls ,winsock //其一 ,ComObj ,WinInet; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } //得到本机的局域网Ip地址 Function GetLocalIp(var LocalIp:string): Boolean; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} {================================================================= 功 能: 返回本机的局域网Ip地址 参 数: 无 返回值: 成功: True, 并填充LocalIp 失败: False =================================================================} function Tform1.GetLocalIP(var LocalIp: string): Boolean; var HostEnt: PHostEnt; Ip: string; addr: pchar; Buffer: array [0..63] of char; GInitData: TWSADATA; begin Result := False; try WSAStartup(2, GInitData); GetHostName(Buffer, SizeOf(Buffer)); HostEnt := GetHostByName(buffer); if HostEnt = nil then Exit; addr := HostEnt^.h_addr_list^; ip := Format('%d.%d.%d.%d', [byte(addr [0]), byte (addr [1]), byte (addr [2]), byte (addr [3])]); LocalIp := Ip; Result := True; finally WSACleanup; end; end; procedure TForm1.Button1Click(Sender: TObject); var IPStr:string; begin GetLocalIP(IPStr); //调用 showmessage(IPStr); end; end. {================================================================= 功 能: 检测计算机是否上网 参 数: 无 返回值: 成功: True 失败: False; =================================================================} function InternetConnected: Boolean; const // local system uses a modem to connect to the Internet. INTERNET_CONNECTION_MODEM = 1; // local system uses a local area network to connect to the Internet. INTERNET_CONNECTION_LAN = 2; // local system uses a proxy server to connect to the Internet. INTERNET_CONNECTION_PROXY = 4; // local system's modem is busy with a non-Internet connection. INTERNET_CONNECTION_MODEM_BUSY = 8; var dwConnectionTypes : DWORD; begin dwConnectionTypes := INTERNET_CONNECTION_MODEM+ INTERNET_CONNECTION_LAN + INTERNET_CONNECTION_PROXY; Result := InternetGetConnectedState(@dwConnectionTypes, 0); end; 各表间的除了索引外,其余的字段不宜重复! 表不宜多,可以设置主从表的形式; 1. 在一系列的radiobutton的单击事件: 两种情况,一是选中的情况下再次单击,二是选中其他radiobutton的情况下单击本radiobutton。 2. “FormName.setfocus;”命令使窗口获得焦点;窗口获得焦点出发ONEnter事件;窗口失去焦点触发OnDeActive事件;OnDeActive事件经常用来编写使窗口不可见或关闭的程序。 3. Ctrl+J:在单元中编写代码的时候,敲入模版 按下Ctrl+J自动产生模版代码 4. 窗体设计中如果要放置多个相同的组件,按住Shift键 + 单击组件,然后在窗体上单击 ,完成后点击选择按钮结束 5. Edit菜单--〉Scale功能:改变窗体上所有组件的位置和大小范围在[25%-400%],包括Left,Top,Width,Height都按照比例改变 6. F8 Step Over :单行/句执行 7. Search菜单下的项目可以快速地按照不同的条件查找、替换代码。 8. 控件布局工具窗口可以方便空间布局:View/Align 9. 在光标处从Code Editor右击选择Debug……加速菜单中选择Add Watch 10. Alt + 左键 块选代码(矩形块,在选对齐的代码时候非常有用); 11. Ctrl+Shift+E光标在Edit窗口和Explorer窗口间切换。(或打开Explorer窗口); 12. Ctrl+Shift+Y 删除光标之后至本行末尾之间的文本。 13. Ctrl+鼠标转轮 加速滚屏。 14. Shitf+箭头 选择 (上下键改变行,左右键改变水平位置 15. CTRL+F弹出查找对话框 ,CTRL+R弹出替换对话框; 16. 常见的code insight 应用: trye+ctrl+j, tryf+ctrl+j, forb+ctrl+j > > for := to do begin end; fors+ctrl+j > > for := to do arrayd+ctrl+j > > array[0..] of ; casee+ctrl+j >> case of : ; : ; else ; end; cases+ctrl+j >> case of : ; : ; end; class+ctrl+j >> if+ctrl+j >> with+ctrl+j >> 1. char是单个字符,pchar是一个指向一个字符串的指针。string是一个字符串。 2. hwnd,hdc是window.h中定义,顾名思义,指窗口句柄和设备环境句柄。在C编程中常用,Delphi中也可以使用,handle属性是Delphi封装的上述各种句柄,对不同对象是不同类型,如:Form1.handle,Application.handle是窗口句柄;Canvas1.handle是设备环境句柄。Brush1.handle是画刷句柄等。 3. VXD是虚拟设备驱动,它通常完成一些系统底层的工作。调用VXD一般时利用Windows API的CreateFile打开设备,然后利用DeviceIoControl来调用VXD。具体的调用办法是由VXD的设计者规定的,需要查看有关的文档说明。 4. DDE是一种动态数据交换机制(Dynamic Data Exchange,DDE)。DDE = Dynamic Data Exchange,是 16 位 Windows 时代实现不同应用程序之间互相交换数据和控制的技术,现在用得很少了,Windows Shell 外壳打开某些文件类型还用到 DDE。 5. CVS是目前比较流行与优秀的版本管理与控制工具,是用来管理其它日常文档(如word工作文档之类)的一个强有力的工具。WinCVS是CVS的一个客户端软件,它运行在Windows上,采用图形化方式登陆CVS服务器和CVS相关的操作与管理,不要学习复杂的cvs命令。企业内部都采用Linux/Unix做服务器,用Windows做客户端,所以WinCVS与CVS服务器是目前应用最广泛的版本控制与管理的组合。 回调函数是应用程序提供给Windows系统DLL或其它DLL调用的函数,一般用于截获消息、获取系统信息或处理异步事件。应用程序把回调函数的地址指针告诉DLL,而DLL在适当的时候会调用该函数。回调函数必须遵守事先规定好的参数格式和传递方式,否则DLL一调用它就会引起程序或系统的崩溃。通常情况下,回调函数采用标准WindowsAPI的调用方式,即__stdcall,当然,DLL编制者可以自己定义调用方式,但客户程序也必须遵守相同的规定。在__stdcall方式下,函数的参数按从右到左的顺序压入堆栈,除了明确指明是指针或引用外,参数都按值传递,函数返回之前自己负责把参数从堆栈中弹出。 动态链接库(Dynamic Link Library,缩写为DLL)是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源。动态链接库文件的扩展名一般是dll,也有可能是drv、sys和fon,它和可执行文件(exe)非常类似,区别在于DLL中虽然包含了可执行代码却不能单独执行,而应由Windows应用程序直接或间接调用。 你老爸是做手艺的,把手艺传给了你,你也会做手艺,这叫重载; 》》"你老爸是做手艺的,把手艺传给了你,你也会做手艺,这叫重载;" 虚拟方法是指能被重载覆盖的方法. ESC键 VK_ESCAPE (27) Insert键: VK_INSERT (45) 方向键(←): VK_LEFT (37) 在DELPHI中除了可以使用RGB(R,G,B)颜色以外,还可以使用系统中给定的颜色常量. 例:EDIT1.COLOR:=CLRED; 颜色常量有: CLAQUA浅绿色. CLBLACK黑色. CLBLUE蓝色. CLDKGRAY灰黑色. CLFUCHSIA紫红色. CLGRAY灰色. CLGREEN绿色. CLLIME橙绿色. CLLTGRAY浅灰色. CLMAROON栗色. CLNAVY深蓝色. CLOLIVE深绿色. CLPURPLE紫色. CLRED红色. CLSILVER银色. CLTEAL水色. CLWHILE白色. CLYELLOW黄色. RGB(R,G,B)分别为RED,GREEN,BLUE取值范围为0~255 function OcttoBin(i: integer): string; //十进制转换为二进制字符串 function BintoOct(k: string): integer; //二进制字符串转换为十进制 function OcttoHex(i: integer): string; //十进制转换为四位的十六进制字符串 function HextoOct(k: string): integer; //十六进制字符串转换为十进制数 function HextoBin(k: string): string; //十六进制字符串转换为二进制字符串 function BintoHex(k: string): string; //二进制字符串转换为四位的十六进制字符串 CTRL+SPACE 代码补全,很好用的(先改了输入法热键) CTRL+SHIFT+I(U) 代码整块移动右移(左移)2个空格 CTRL+SHIFT+T 在光标行加入TO-DO注释 Ctrl + Alt + c CPU窗口 Ctrl + Alt + F FPU窗口 Ctrl + Alt +V 事件日志窗口 Ctrl + Alt +M 模型窗口 Ctrl + Alt + B 断点查看窗口 Ctrl +F 查找 Ctrl + R 替代 CTRL+鼠标转轮 加速滚屏 CTRL+Y 删除光标所在行 CTRL+HOME 将光标移至文件头 F11 显示属性窗口 Delphi编译错误,运行错误,操作系统错误速查2008-04-05 19:21******************************* * 编 译 错 误 信 息 * ******************************* ';' not allowed before 'ELSE' ElSE前不允许有“;” ' ' ' 'GOTO 范围 16-Bit fixup encountered in object file ' 486/487 instructions not enabled 不能用486/487指令 Abstract methods must be virtual or dynamic 抽象方法必须为虚拟的或动态的 Array type required 需要数组类型 Assignment to FOR-Loop variable ' Bad argument type in variable type array constructor 在变量类型数组结构中不正确的参数类型 Bad file format ' Bad file format: Bad global symbol definition: ' Bad unit format: BREAK or CONTINUE outside of loop BREAK或CONTINUE超出循环 Cannot add or subtract relocatable symbols 不能增加或减少可重置的符号 Cannot assign to a read-only property 不能指定只读属性 Cannot BREAK, CONTINUE or EXIT out of a FINALLY clause 超出FINALLY子句的范围,不能使用BREAK,CONTINUE或EXIT语句 Cannot initialize local variables 不能初始化局部变量 Cannot initialize multiple variables 不能初始化多个变量 Cannot initialize thread local variables 不能初始化线程局部变量 Cannot override a static method 不能覆盖静态方法 Cannot read a write-only property 不能读取只写属性 Case label outside of range of case expression CASE标号超出了CASE表达式的范围 Circular unit reference to Class already has a default property 类已具有默认的属性 Class does not have a default property 类没有默认的属性 Class or object types only allowed in type section 在类型区段只允许有类或对象类型 Class type required 需要类类型 Close error on Compile terminated by user 用户中止编译 Constant expected 要求常量 Constant expression expected 要求常量表达式 Constant expression violates subrange bounds 常量表达式超出子界范围 Constant object cannot be passed as var parameter 常量对象不能作为变量参数传递 Constant or type identifier expected 要求常量或类型标识符 Constants cannot be used as open array arguments 常量不能用作打开数组参数 Constructing instance of ' Could not compile used unit ' Could not create output file Could not load RLINK32.DLL 不能加载RLINK32.DLL Data type too large: exceeds 2 GB 数据类型太大:超过2GB Declaration of Default property must be an array property 默认的属性必须为数组属性 Default values must be of ordinal, pointer or small set type 默认的值必须为序数、指针或小集类型 Destination cannot be assigned to 目标不能指定 Destination is inaccessible 目标不能存取 Dispid ' Dispid clause only allowed in OLE automation section DISPID子句只能在OLE自动区段中使用 Division by zero 除数为零 Duplicate case label CASE标号重复 Duplicate tag value 重复的标志值 Dynamic method or message handler not allowed here 这里不允许有动态方法或信息处理程序 Dynamic methods and message handlers not allowed in OLE automation section在OLE自动区段不允许有动态方法或消息处理程序 Element 0 inaccessible - use 'Length' or 'SetLength' 元素0不能存取-使用LENGTH或SETLENGTH Error in numeric constant 数值常量错误 EXCEPT or FINALLY expected 要求EXCEPT或FINALLY EXPORTS allowed only at global scope EXPORTS只允许在全局范围使用 Expression has no value 表达式没有值 Expression too complicated 表达式太复杂 Field definition not allowed in OLE automation section 在OLE自动区段中不允许域定义 Field definition not allowed after methods or properties 在方法或属性后不允许域定义 Field or method identifier expected 要求域或方法标识符 File not found: File type not allowed here 这儿不允许文件类型 For loop control variable must be simple local variable FOR循环控制变量必须为简单局部变量 For loop control variable must have ordinal type FOR循环控制变量必须为序数类型 FOR or WHILE loop executes zero times - deleted FOR或WHILE循环执行零次-删除 FOR-Loop variable ' FOR-Loop variable ' Function needs result type 函数需要结果类型 Identifier redeclared: ' Illegal character in input file: ' Illegal message method index 非法的消息方法指针 Illegal reference to symbol ' Illegal type in OLE automation section: ' Illegal type in Read/Readln statement 在Read/Readln语句中的非法类型 Illegal type in Write/Writeln statement 在Write/Writeln语句中的非法类型 Inaccessible value 不可存取的值 Incompatible types: ' Incompatible types: Inline assembler stack overflow 内联汇编溢出 Inline assembler syntax error 内联汇编语法错误 Instance variable ' Integer constant or variable name expected 要求整形常量或变量名 Integer constant too large 整型常量太大 Internal error: Invalid combination of opcode and operands 操作码与操作对象的无效组合 Invalid compiler directive: ' Invalid function result type 无效的函数值类型 Invalid message parameter list 无效的消息参数列表 Invalid register combination 无效的寄存器组合 Invalid typecast 无效的TYPECASE Label ' Label already defined: ' Label declaration not allowed in interface part 在界面部分不允许标号说明 Label declared and referenced, but not set: ' Label expected 要求标号 Left side cannot be assigned to 左边不能赋值 Line too long (more than 255 characters) 行太长(超出255个字符) Local class or object types not allowed 不允许局部的类或对象类型 Local procedure/function ' LOOP/JCXZ distance out of range LOOP/JCXZ距离超出范围 Low bound exceeds high bound 下界超过上界 Memory reference expected 要求内存引用 Method ' Method ' Method identifier expected 要求方法标识符 Missing ENDIF directive 缺少ENDIF指令 Missing operator or semicolon 缺少操作符或分号 Missing or invalid conditional symbol in '$ Missing parameter type 缺少参数类型 Necessary library helper function was eliminated by linker 必要的库帮助函数被连接程序删除 No definition for abstract method ' Not enough actual parameters 没有足够的实际参数 Number of elements differs from declaration 元素数与说明不同 Numeric overflow 数值溢出 Object or class type required 需要对象或类类型 Object type required 需要对象类型 Only register calling convention allowed in OLE automation section 在OLE自动区段中只允许寄存器调用约定 Operand size mismatch 运算对象大小匹配 Operator not applicable to this operand type 运算符不使用于这一运算对象类型 Order of fields in record constant differs from declaration 在记录常量中的域次序与说明不同 Ordinal type required 需要序数类型 Out of memory 内存溢出 Overflow in conversion or arithmetic operation 转换或算术操作溢出 Overriding automated virtual method ' PACKED not allowed here 这里不允许PACKED Pointer type required 需要指针类型 Procedure cannot have a result type 过程不能有结果类型 Procedure DISPOSE needs destructor 过程DISPOSE需要destructor Procedure FAIL only allowed in constructor 过程FAIL只允许在constructor方法中 Procedure NEW needs constructor 过程NEW需要constructor方法 PROCEDURE or FUNCTION expected 要求PROCEDURE或FUNCTION Procedure or function name expected 要求过程或函数名 Program or unit ' Property ' Published property ' Published Real48 property '< name>' must be Single, Double or Extended Published REAL属性< NAME>必须为Single, Double或Extended Re-raising an exception only allowed in exception handler 在意外处理中只允许重新引起意外处理 Read error on Record, object or class type required 需要记录,对象或类类型 Redeclaration of ' Redeclaration of property not allowed in OLE automation section 在OLE自动区段中不允许属性重复说明 Return value of function ' Seek error on Segment/Offset pairs not supported in Borland 32-bit Pascal 在Borland 32位的PASCAL中不支持Segment/Offset对 Sets may have at most 256 elements 集至少有256个元素 Size of published set ' Slice standard function only allowed as open array argument Slice标准函数只允许作为打开数组参数 Statement expected, but expression of type ' Statements not allowed in interface part 在界面中不允许的语句 String constant too long 字符串常量太长 String constant truncated to fit STRING[ Strings may have at most 255 elements 字符串至少255个元素 Structure field identifier expected 要求结构域标识符 Syntax error in real number 实数语法错误 System unit out of date or corrupted: missing ' Text after final 'END. 编译器忽略END.后的文本 This form of method call only allowed for class methods 该方法的窗体只允许类方法 This form of method call only allowed in methods of derived types 该方法的窗体只允许在导出类型的方法中 This type cannot be initialized 这一类型不能初始化 Thread local variables cannot be ABSOLUTE 线程局部变量不能是ABSOLUTE Thread local variables cannot be local to a function or procedure 线程局部变量对函数不能是局部的 Too many actual parameters 太多的实际参数 Too many conditional symbols 太多的条件符号 Type ' Type ' Type ' Type ' Type ' Type ' Type expected 要求TYPE Type not allowed in OLE Automation call 在OLE自动调用中不允许的类型 Type of expression must be BOOLEAN 表达式的类型必须为BOOLEAN型 Type of expression must be INTEGER 表达式的类型必须为INTEGER型 TYPEINFO standard function expects a type identifier TYPEINFO标准函数要求类型标识符 TYPEOF can only be applied to object types with a VMT TYPEOF只能用于具有VMT的对象类型 Types of actual and formal var parameters must be identical 形参与实参必须一致 Undeclared identifier: ' Unexpected end of file in comment started on line Unit Unit name mismatch: ' Unknown directive: ' Unnamed arguments must precede named arguments in OLE Automation call 在OLE自动调用中未命名的参数必须在命名的参数前 Unsatisfied forward or external declaration: ' Unterminated string 未结束的字符串 Value assigned to ' Variable ' Variable ' Variable ' Variable required 需要变量 Virtual constructors are not allowed 不允许虚拟的constructors方法 Write error on Wrong or corrupted version of RLINK32.DLL RLINK32.DLL版本错误或不能用 ******************************* * 运 行 错 误 信 息 * * 运行时出现的错误信息形式为: * * Run-time error nnn at xxxx * * 其中 nnn 是运行时的错误编号 * * xxxx 是运行时的错误地址 * ******************************* 运行时的错误分为以下三类: * I/O错误:错误编号为100-149 编号 说明 --------------------------------------------------------- 100 磁盘读错误,若要对超过格式文件尾进行读取时 101 磁盘写错误,若磁盘满时,由CloseFile,Write,Writeln或Flush报告 102 没有指定文件,若文件变量没有由Assign或AssignFile赋值,由Reset,Rewrite,Append,Rename和Erase报告 103 文件没有打开,若文件未打开,由CloseFile,Read,Write,Seek,Eof,FilePos,FileSize,Flush,BlockRead或BlockWrite报告 104 输入文件未打开,由Read,Readln,Eof,Eoln,SeekEof或SeekEoln报告有关输入的文本文件未打开 105 输出文件未打开,由Write和Writeln报告有关文本文件没有用Console应用程序生成 106 无效的数据格式,由Read或Readln报告从文本文件读取的数据格式不正确 * 致命错误:错误编号为200-255 编号 说明 200 被零除 201 范围检查错误 202 栈上溢 203 栈上溢错误 204 无效的指针操作 205 浮点上溢 206 浮点下溢 207 无效的浮点操作 215 算术上溢错误 216 存取非法 217 控制-C 218 授权指令 219 无效的TYPECAST 220 无效的变体TYPECAST 221 无效的变体操作 222 没有变体方法调用DISPATCHER 223 不能建立变体数组 224 变体不包含数组 225 变体数组边界错误 226 TLS初始化错误 操作系统错误 编号 说明 --------------------------------------------------------- 1899L 不能生成端点映射数据库 1752L 不能执行操作 1751L 入口点非法 1753L 端点映射中没有更多可用的端点 5L 存取非法 1331L 帐号当前不能用,因此不能登录 1793L 用户帐号过期 1327L 用户名是有效的,但一些限制不能验明用户 57L 网络适配器硬件错误 1379L 指定的别名已存在 1344L 分配用于更新的内存块不足 85L 本地设备名已在使用 183L 试图建立已存在的文件 1074L 系统当前正以最新最好的配置运行 7L 存储控制块被破坏 534L 运算结果超出32位 174L 文件系统不支持锁定类型的原子变化 199L 操作系统不能运行这一程序 160L 传递给DosExecPgm的参数串不正确 22L 设备不能识别的命令 1361L 安全描述符不在要求的格式 66L 网络资源类型不正确 1200L 指定的设备名无效 119L 系统不支持请求的命令 10L 环境不正确 193L %1不是有效的基于Windows的应用程序 11L 企图装载不正确格式的程序 1346L 指定的模拟级无效或没有提供要求的模拟级 1340L 试图建立继承的ACL或没有继承的ACE 24L 程序指定的命令长度不正确 1365L 登录段与要求的操作状态不一致 67L 网络名找不到 58L 指定的服务器不能执行请求的命令 53L 网络路径没有找到 161L 指定的路径名无效 230L 管道状态无效 1206L 网络连接协议被损坏 1204L 指定的网络提供者名无效 60L 远程适配器不兼容 159L 线程ID地址不正确 1349L 符号对象类型不当 20L 系统不能找到指定的设备 2202L 指定的用户名无效 1348L 请求的确定信息类是无效的 1009L 配置记录数据库被破坏 1010L 配置记录密钥无效 1102L 遇到磁带头或分区 1076L 当前引导已接受为最新的控制设置 109L 管道结束 111L 文件名太长 1111L I/O总线重新设置 170L 请求的资源在使用 142L 此时系统不能执行JOIN或SUBST 120L 输入的API只能在Windows/NT模式下工作 1003L 由于一些原因不能完成的功能 173L 锁定请求对提供撤消区未解决 266L 不能使用 1407L 不能找到Windows类 1368L 表示要试图通过命名管道的模拟还没有读取 82L 不能生成目录或文件 1205L 不能打开网络连接协议 1351L 没有联系的域控制器或在域内对象被保护,因此不能存取必要信息 1310L 委托组不能禁止 1347L 试图打开匿名的符号,匿名级的符号不能打开 1011L 配置记录密钥不能打开 1012L 配置记录密钥不能读取 1013L 配置记录密钥不能写 1021L 试图在易变的父关键字下建立稳定的子关键字 129L 应用程序%1不能在Windows模式下运行 1436L 子窗口不能有菜单 1059L 指定子循环服务从属 1410L 类已存在 1411L 类不存在 1412L 类仍在打开的窗口中 1418L 线程没有打开的剪切板 1201L 设备当前没有连接,但要记住连接 1421L 没有找到控制ID 1121L 由于超时已到,一系列的I/O操作完成 23L 数据错误 16L 目录不能删除 1065L 指定的数据库不存在 1425L 传递给ReleaseDC的无效HDC 1051L 终止控制已送到其他独立运行服务的服务中 1435L 不能破坏其他线程产生的对象 55L 指定的网络资源不再有效 1202L 试图记住先前记住的设备 2404L 设备由激活的进程在使用,不能断开连接 1107L 当装载磁带时,找不到磁带的分区信息 145L 目录非空 144L 目录不是根目录的子目录 130L 试图使用文件句柄来打开磁盘操作 267L 目录名无效 157L 段已丢失,不能锁定 107L 由于没有插入交换磁盘,程序终止 1393L 磁盘结构损坏,不能在读取 112L 磁盘上没有足够的空间 1127L 即使重试,存取硬盘也失败 1126L 在存取硬盘时,即使重试,存取校准操作也失败 1128L 即使磁盘控制器重新设置,存取硬盘也失败 1114L DLL初始化例程失败 1356L 指定的域已存在 1357L 在该版本中试图超出每个服务器域的限制 1810L 指定域的名字或安全ID与该域的受托信息不一致 108L 磁盘在使用或被其他进程锁定 1221L 工作族或域名已被网络上的其他计算机使用 52L 网络上存在重名 1078L 名字已在作服务器名或服务显示名使用 196L 操作系统不能运行这一应用程序 994L 对EA的存取非法 276L 在安装文件系统上的EA文件被损坏 255L EA不一致 277L 在安装文件系统的EA文件上的EA表用完 275L EA不适合在缓冲区中 282L 安装文件系统不支持扩展属性 1100L 在操作中出现磁带尾部标志 203L 系统不能找到输入的环境选项 1129L 遇到磁带的物理尾部 1501L 没有打开的日志文件事件,因此事件登录服务没有启动 1503L 在读取之间事件日志文件已改变 1500L Eventlog登录文件之一破坏 1064L 在处理控制请求时出现意外 101L 专门信号被其他进程所拥有 192L 操作系统不能运行%1 1208L 出现扩展错误 83L INT24失败 1063L 服务进程不能连接到服务控制器 1392L 文件或目录被损坏,不能在读取 80L 文件存在 1006L 文件卷已变化,因此打开的文件不再有效 2L 系统不能找到指定的文件 1101L 磁带存取达到文件标志 206L 文件名或后缀太长 1125L 软盘控制器返回与登记不一致的结果 1122L 在软盘上没有找到ID地址标志 1123L 软盘扇区ID域与软盘控制器道地址不匹配 1124L 软盘控制器报告出现不能由软驱识别的错误 1007L 请求的操作在全屏幕模式不能执行 31L 连接到系统上的设备不正常 1360L 通配存取类型包含在存取屏蔽中 1429L 该异常分支只能为全局设置 1318L 指定的组已存在 39L 磁盘满 38L 到达文件末 1428L 没有模块处理,不能设置非局部的异常处理 1431L 异常分支没有安装 1409L 热键已登记 1419L 热键没有登记 1441L 所有的DeferWindowsPosHWND必须具有相同的父 1324L 在更新口令时,该返回状态表示新口令中包含不允许的值 202L 操作系统不能运行%1 122L 传递给系统调用的数据区太小 1358L 由于灾难性的介质错误或磁盘数据结构破坏引起请求的操作不能完成 1383L LSA数据库内部不一致 1359L SAM遇到内部数据库不一致的错误,可防止SAM的进一步操作 1800L 指定的优先级无效 1448L 滚动条范围大于0x7FFF 1338L 安全描述符结构无效 198L 操作系统不能运行%1 180L 系统检测到不正确的段号 1799L 指定的分隔符文件无效 1352L SAM服务器状态错误,不能完成期望的操作 1057L 帐号名无效或不存在 1052L 对该服务请求的控制无效 1071L 指定的服务数据锁定无效 1213L 指定的服务名格式无效 1215L 指定的共享名格式不正确 1449L SHOWWINDOWS命令无效 1337L SID结构无效 209L 公布的信号不正确 1439L 参数无效 189L 操作系统不能运行%1 188L 操作系统不能运行%1 1335L 子权限值无效 114L 目标内部文件标识符不正确 1444L 线程ID无效 1784L 提供的用户缓冲区对请求操作失效 118L 写后验证开关参数值不正确 1400L 窗口处理无效 1329L 用户帐号限制,不能从源工作站登录 1117L 由于I/O设备错误,请求不能完成 996L 重叠的IO时间不在发信号状态 997L 重叠的IO操作在处理中 197L 操作系统当前不能配置来运行应用程序 1119L 不能打开与其它设备共享IRQ的设备,至少有一使用该IRQ的其他设备已打开 147L 没有足够的可用资源来处理这一命令 133L 由于驱动器已包含连接,JOIN或SUBST命令不能使用 134L 试图在已连接的驱动器上使用JOIN或SUBST命令 146L 指定的路径正在用替换 149L 试图替代先前已替代的驱动器目录 135L 试图在已替代的驱动器上使用JOIN或SUBST命令 194L 操作系统不能运行%1 138L 系统试图替代已替代的目录 140L 系统试图替代已替代的目录 1430L 日常异常处理已安装 1018L 在有删除标志的登记键上非法操作 1020L 试图在已有子键或值的登记键建立符号连接 154L 输入的卷标超过11个字符的限制,前11个字符写在磁盘上,其余字符自动删除 1322L 请求的操作被禁止或删除最新的其余管理员帐号 1434L 该列表框不支持制表符 1416L 列表符ID没有找到 1390L 试图修改用户口令,但没有提供要求的LM口令 1303L 联接局部RPC,要求用户话路密钥 167L 试图锁定文件失败的区域 33L 由于其他进程已锁定部分文件,该文件不能被进程存取 212L 端锁定,因此不能重新分配 1502L 事件登录文件已满 1326L 由于用户名或验证信息不正确,试图登录无效 1380L 请求登录的类型(如网络,服务等)没有被目标系统授权 1366L 登录话路ID已在使用 1363L 试图启动新的话路管理程序或用已在使用的LSA登录话路 1385L 请求登录的类型(如网络,服务等)没有授权 1334L 没有更多可分配的LUID 164L 在系统中不能生成更多的线程 1110L 驱动器中的介质已改变 1378L 指定的帐号名不是别名的成员 1320L 指定的用户帐号已在指定的组帐号中或由于组中有成员,不能删除 1377L 指定的帐号名不是别名的成员 1321L 指定的用户帐号不是指定组帐号的成员 1374L 由于组是基本组,因此成员不能从该组中删除 208L 取决文件名符号*或?输入不正确或指定的全局文件符号更多 126L 不能找到指定的模块 234L 需要更多的数据 1120L 一系列的I/O操作被其他写到串口的操作完成 317L 系统不能找到消息号为0x%1的消息 131L 试图在超出文件头的位置移动文件指针 215L 不能嵌套调用LoadModule 1792L 试图登录,但网络登录服务没有启动 88L 网络写失败 64L 指定的网络名不再有效 65L 网络存取非法 54L 网络在忙 6118L 该工作组的服务器列表当前不可用 232L 管道在进程中关闭 1104L 在磁带存取中,到达数据标志尾部 1309L 试图由当前不在模拟客户的线程上操作模拟符号 1391L ACL不包含可继承的组件 1019L 系统不能分配记录文件要求的空间 1807L 使用的帐号在内域受托帐号中,使用正常的帐号或远程用户帐号来存取该服务器 1809L 使用的帐号在服务器受托帐号中,使用正常的帐号或远程用户帐号来存取该服务器 1311L 当前没有可用的登录服务器来服务登录请求 1808L 使用的帐号在工作站受托帐号中,使用正常的帐号或远程用户帐号来存取该服务器 1112L 由于驱动器中没有介质,磁带查询失败 18L 没有更多的文件 259L 没有更多的可用数据 113L 没有更多的可用内部文件标识符 1203L 没有网络提供者接收给定的路径 2138L 没有网络或网络未启动 89L 此时系统不能启动另一进程 1302L 对该帐号没有指定限额 1447L 窗口不能有滚动条 1350L 试图对没有安全性的对象操作 1116L 由于没有关机在处理中,试图放弃关机失败 205L 在命令子树中没有进程有信号句柄 62L 在服务器上存储等待打印文件的空间不足 1376L 指定的别名不存在 1355L 指定的域不存在 1319L 指定的组不存在 1312L 指定的登录话路不存在,可能已终止 1387L 不存在的新成员不能添加到别名中 1364L 指定的验证包未知 1313L 指定的特权不存在 1317L 指定的用户不存在 1437L 窗口不能具有系统菜单 1008L 试图引用不存在的符号 1786L 工作站没有受托秘密 1787L 域控制器对该工作站没有帐号 1113L 对目标多字节代码页存在的Unicode字符没有映射 1394L 对指定的登录话路没有用户话路密钥 125L 磁盘没有卷标 1417L 没有找到通配符 998L 对内存位置的无效存取 1445L 用非MDI子窗口调用DefMDIChildProc 1332L 映射的信息没有转变 1300L 不是所有权限赋给调用者 1442L 窗口不是子窗口 2250L 网络连接不存在 1207L 不能枚举非容器 26L 指定的磁盘不能存取 8L 没有足够的空间处理该命令 1130L 没有足够的空间处理该命令服务器 136L 系统试图删除没有连接的驱动器 158L 段已锁定 1362L 请求的动作只受登录进程的限制,调用进程没有登记为登录进程 288L 试图释放不被调用者拥有的互斥法 21L 驱动器没有准备好 1017L 系统试图装载或恢复文件到登记中,但指定的文件格式不正确 17L 系统不能将文件移动到不同的驱动器上 137L 系统试图删除没有替代的驱动器 50L 不支持网络请求 1022L 改变请求正在完成,信息没有返回在调用者的缓冲区.调用者现在需要模拟文件,以找到所做的修改 1386L 没有提供必要的NT交叉保密口令而试图以安全帐号管理员改变用户口令 1304L WindowsNT的口令太复杂,无法将其转换为Windows的网络口令(该口令返回NULL字符串) 110L 系统不能打开指定的设备或文件 2401L 有打开文件或请求在连接期 995L 由于线程退出或应用程序请求,I/O操作放弃 28L 打印机没有纸 84L 处理该请求没有足够的空间 14L 处理该操作没有足够的空间 1105L 磁带没有分区 1330L 用户帐号的口令已到期 1325L 在更新口令,该状态表示违反一些口令更新规则 148L 指定的路径现在不能用 3L 系统不能找到指定的路径 231L 所有的管道实体在忙 535L 在管道的另一端有进程 536L 等待进程打开管道的另一端 233L 在管道的另一端没有进程 1446L 下拉式菜单已激活 1131L 已检测到潜在的僵局条件 63L 要打印的等待文件被删除 1802L 打印机已存在 1795L 指定的打印驱动程序已安装 61L 打印队列已满 1415L 使用局部的DIALOG窗口字 1314L 请求的权限客户机没有 127L 指定的过程没有找到 1067L 进程突然终止 30L 系统不能从指定的驱动器读取 72L 指定的打印机或磁盘驱动器已暂停 1794L 重定向器在使用,不能卸载 1015L 登记文件的文件结构或文件的内存印象系统损坏或文件不能恢复 1016L 登记初始化I/O操作有不可恢复的错误,登记不能完成读,写等操作 1014L 包含系统登记数据的文件之一已恢复成功 201L 操作系统不能运行%1 51L 远程计算机不可用 1220L 试图建立LAN管理服务器话路,但已建立了很多 71L 网络请求不接受 1816L 处理该命令没有足够的定额 1812L 指定的图象文件不包含资源部分 1815L 指定的资源语言ID在图象文件中找不到 1814L 指定的资源名在图象文件中找不到 1813L 指定的资源类型在图象文件中找不到 1306L 两个版本级不兼容 207L 2环堆栈在使用 200L 代码段不能大于等于64KB 1370L 在登记事务委托中出现错误 1369L 登记子树的事务状态与请求的操作不兼容 143L 系统不能替代相同的驱动器或目录 1440L 屏幕已锁定 1382L 秘密的长度超出允许的最大长度 27L 驱动器没有找到请求的扇区 25L 驱动器不能找到磁盘上指定的区域和道 132L 文件指针不能设置在指定的设备或文件上 102L 信号设置不能关闭 187L 指定的系统信号名没有找到 105L 该信号的先前物主关系已终止 121L 信号超时期已到 106L 在驱动器1中插入磁盘 1118L 串行设备没有初始化,串行设备没有安装 1341L GUID分配服务器此时禁止 1811L 服务器在使用中,不能卸载 1342L 此时允许GUID分配服务器 1056L 服务实体已在运行 1061L 服务在此时不能接受控制消息 1055L 服务数据库锁定 1075L 从属服务不存在或已做删除标志 1068L 从属服务或组启动失败 1058L 指定服务禁止,不能启动 1060L 指定作为安装的服务不存在 1073L 指定的服务已存在 1069L 由于登录失败,服务不能启动 1072L 指定的服务已做删除标志 1077L 引导后没有启动的服务已启动 1054L 不能产生该服务的线程 1062L 服务没有启动 1053L 服务对启动没有响应或及时地控制请求 1066L 服务已返回一服务指定错误代码 1070L 在启动后,服务挂在启动等待状态 1219L 提供的证书与已有证书集冲突 1433L LB_SETCOUNT发送到非缓慢的列表框 1103L 磁带存取达到设置标志 36L 打开的共享文件太多 70L 远程服务暂停或在启动的过程中 32L 由于文件被其他进程使用,该进程则不能存取 1115L 系统关闭在处理中 162L 信号已暂挂 156L 接受进程拒绝信号 1301L 要映射的一些信息没有传送 1371L 试图在与内置帐号不兼容的SAM帐号上操作 1372L 请求的操作不能在指定的组上执行,由于它的内置的特殊组 1373L 请求的操作不能在指定的用户上执行,由于它的内置的特殊组 1001L 递归太深,堆栈溢出 141L 系统试图SUBST一驱动器到已替代驱动器的目录 139L 系统试图替代一驱动器到已替代驱动器的目录 0L 操作成功的完成 999L 存取分页的文件错误 150L 系统追踪的信息不在指定的CONFIG.SYS文件中或追踪不允许 210L 信号句柄没有设置 1406L CreateWindows失败,建立WS_CHILD类的顶级窗口 1375L 试图建立作为基本使用的符号,但该符号已在使用.一次只能有一个基本的符号 56L 已达到网络BIOS命令限制 1384L 在试图登录中,用户的安全堆集太多的安全ID 1333L 请求的LUD数不能在单个的分配中分配 214L 太多的动态连接模块连接到该程序中或动态模块中 152L 已设置太多的信号 68L 超出局域网网卡的名字限制 4L 系统不能打开该文件 298L 给信号太多的邮件 1381L 在单个系统中可存储的最大秘密数超出 103L 信号不能重新设置 100L 不能建立另一系统信号 69L 网络BIOS话路超出 1389L 指定太多的SID 155L 不能建立另一线程 1790L 网络登录失败 1788L 在主域与受托域之间的受托关系失败 1789L 在工作站与主域之间的受托关系失败 1108L 试图锁定缺少弹出介质的机构 1109L 卸载介质失败 59L 出现意外的网络错误 1796L 指定的处理器未知 1798L 打印处理器未知 1797L 打印驱动器未知 1305L 遇到或指定的版本对服务来说未知 1785L 磁盘介质不能辨认,可能是未格式化 1005L 卷不包含识别文件系统 1316L 指定的用户已存在 240L 话路取消 128L 没有等待的子进程 1423L 窗口不是一命令框 1420L 窗口不是一有效的对话框 1408L 无效的窗口,属于其他的线程 29L 系统不能写到指定的驱动器 19L 介质写保护 34L 驱动器中错误的磁盘,将%2(卷系列号%3)插入到驱动器%1中 1323L 在更新口令时,该状态表示提供的口令值不正确 -1L 无效的输入句柄 -2L 无效的输入句柄 -7L 输入参数超出范围 -5L LZFile文件结构内存不足 -6L 不正确的全局句柄 -3L 损坏的压缩文件结构 -4L 输出文件空间不足 -8L 不能识别的压缩算法 0L 没有错误 1768L 在服务器中出现编址错误 1713L 服务器已在听从 1711L 对象UUID已登记 1746L 连接不包含鉴别信息 1726L 远程过程调用失败 1727L 远程过程调用失败,不能执行 1791L 远程过程调用已在该线程处理中 1764L 不支持请求的操作 1720L 不能生成端点 1740L 端点重复 1760L 入口已存在 1761L 入口没有找到 1769L 在服务器上的浮点操作被零除 1771L 在服务器上出现浮点上溢 1770L 在服务器上出现浮点下溢 1898L 组成员没有找到 1755L 入口名不完善 1759L 界面没有找到 1766L 在RPC中出现内部错误 1749L 安全上下文无效 1702L 连接句柄无效 1734L 数组边界无效 1706L 端点格式无效 1736L 名称语法无效 1707L 网络地址无效 1724L 网络选项无效 1900L 对象通用唯一标识符为空 1704L RPC协议序列无效 1700L 字符串连接无效 1705L 字符串UUID失效 1733L 标志无效 1709L 超时值无效 1756L 版本选项无效 1742L 调用的最大数太小 1762L 命名服务不可用 1718L 没有连接 1725L 在该线程中没有远程过程调用 1765L 允许的模拟没有安全上下文可用 1708L 没有找到端点 1735L 连接不包含入口点名 1806L 没有足够的连接 1757L 没有足够的成员 1719L 没有协议序列 1714L 没有登记的协议序列 1715L 服务器没有听从 1710L 对象UUID没有找到 1721L 没有足够的资源完成该操作 1745L 过程号超出范围 1728L 出现RPC协议错误 1744L RPC协议序列没有找到 1703L 不支持RPC协议序列 1731L 服务器没有足够的内存完成该操作 1723L 服务器太忙,不能完成该操作 1722L 服务器不可用 1743L 字符串太长 1712L 类型UUID已登记 1748L 未知的鉴别级 1747L 未知的鉴别服务 1741L 未知的鉴别类型 1750L 未知的授权服务 1717L 未知的界面 1716L 未知的管理类型 1737L 不支持命令语法 1730L 服务器不支持转换语法 1732L 不支持类型UUID 1739L 没有可用于构造UUID的网络地址 1701L 连接处理为不正确的类型 1767L 服务器试图做整数被零除 1783L 存根接收到不正确的数据 1782L 字节计算太小 1781L 枚举值超界 1772L 用于自动处理连接的可用服务器已用完 1780L 空引用指针传递到存根 1779L 存根不能得到调用句柄 1773L 由DCERPCCHARTRANS指定的文件不能打开 1774L 包含字符转换表的文件小于512KB 1777L 在调用中上下文处理改变 1776L 上下文句柄与任何已知的不匹配 1778L 传递给远程调用的连接句柄不匹配 1775L 空的上下句柄作为参数传递 箭头类: E:\资料\图标库\17292.ICO\其它\Arrows 小手: E:\资料\图标库\17292.ICO\其它\hand XP系统 E:\资料\图标库\17292.ICO\其它\xp 特别是E:\资料\图标库\17292.ICO\其它\xp\XP Set 精美球形图标 E:\资料\图标库\17292.ICO\winxp\ball\ball E:\资料\图标库\17292.ICO\winxp\bubbles1 E:\资料\图标库\17292.ICO\winxp\bubbles2 办公小物品(文具,图钉等办公室物品) E:\资料\图标库\17292.ICO\办公\稳定 电脑设备 E:\资料\图标库\17292.ICO\电脑 1.数论算法 (部分背包问题可有贪心法求解:计算Pi/Wi) >>文件链接 >>优先级 tpIdle The thread executes only when the system is idle. The system will not interrupt other threads to execute a thread with tpIdle priority. tpLowest The thread's priority is two points below normal. tpLower The thread's priority is one point below normal. tpNormal The thread has normal priority. tpHigher The thread's priority is one point above normal. tpHighest The thread's priority is two points above normal. tpTimeCritical The thread gets highest priority. >>属性: Priority threaded FreeOnTerminate Terminated suspended. >>方法: Execute: Provides an abstract or pure virtual method to contain the code which executes when the thread is run. Suspend Resume Terminate WaitFor Waits for the thread to terminate and then returns the value of the ReturnValue property. >>Ord() 返回序数类的序数 >>Odd() 测试参数是否为奇数 //function Odd(X: Longint): Boolean; >>function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer; %FindFirst returns 0 if a file was successfully located, otherwise, it returns an error code. % 查看帮助主题FindFirst function >>function FileGetAttr(const FileName: string): Integer; %Returns the file attributes of FileName. >> MessageBox(const Text, Caption: PChar; Flags: Longint = MB_OK): Integer; 帮助主题MessageBox Flags : MB_ABORTRETRYIGNORE,MB_OK, MB_OKCANCEL ,MB_RETRYCANCEL,MB_YESNO,MB_YESNOCANCEL ①procedure GetMem(var P: Pointer; Size: Integer); >> Creates a dynamic variable and a pointer to the address of the block.//开辟内存? ②procedure FreeMem(var P: Pointer[; Size: Integer]); >>Disposes of a dynamic variable of a given size. //释放内存 ③procedure FreeAndNil(var Obj); >>Frees an object reference and replaces the reference with Nil. ④ ⑤ 有三个API函数可以运行可执行文件WinExec、ShellExecute和CreateProcess。CreateProcess因为使用复杂,比较少用。 WinExec主要运行EXE文件。如:WinExec('Notepad.exe Readme.txt', SW_SHOW); ShellExecute不仅可以运行EXE文件,也可以运行已经关联的文件。 首先必须引用shellapi.pas单元:uses ShellAPI; 1.标准用法 ShellExecute函数原型及参数含义如下: function ShellExecute(hWnd: HWND; Operation, FileName, Parameters,Directory: PChar; ShowCmd: Integer): HINST; stdcall; ●hWnd:用于指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口。例如,可以将其设置为应用程序主窗口句柄,即Application.Handle,也可以将其设置为桌面窗口句柄(用GetDesktopWindow函数获得)。 ●Operation:用于指定要进行的操作。其中“open”操作表示执行由FileName参数指定的程序,或打开由FileName参数指定的文件或文件夹;“print”操作表示打印由FileName参数指定的文件;“explore”操作表示浏览由FileName参数指定的文件夹。当参数设为nil时,表示执行默认操作“open”。 ●FileName:用于指定要打开的文件名、要执行的程序文件名或要浏览的文件夹名。 ●Parameters:若FileName参数是一个可执行程序,则此参数指定命令行参数,否则此参数应为nil或PChar(0)。 ●Directory:用于指定默认目录。 ●ShowCmd:若FileName参数是一个可执行程序,则此参数指定程序窗口的初始显示方式,否则此参数应设置为0。 若ShellExecute函数调用成功,则返回值为被执行程序的实例句柄。若返回值小于32,则表示出现错误。 上述仅仅是ShellExecute函数的标准用法,下面将介绍它的特殊用法。 2.特殊用法 如果将FileName参数设置为“http:”协议格式,那么该函数将打开默认浏览器并链接到指定的URL地址。若用户机器中安装了多个浏览器,则该函数将根据Windows 9x/NT注册表中http协议处理程序(Protocols Handler)的设置确定启动哪个浏览器。 格式一:http://网站域名。 如:ShellExecute(handle, ‘open’, http:// ; www.neu.edu.cn’, nil, nil, SW_SHOWNORMAL); 格式二:http://网站域名/网页文件名。 如:ShellExecute(handle, ‘open’, http:// ; www.neu.edu.cn/default.htm’,nil,nil, SW_SHOWNORMAL); 如果将FileName参数设置为“mailto:”协议格式,那么该函数将启动默认邮件客户程序,如Microsoft Outlook(也包括Microsoft Outlook Express)或Netscape Messanger。若用户机器中安装了多个邮件客户程序,则该函数将根据Windows 9x/NT注册表中mailto协议处理程序的设置确定启动哪个邮件客户程序。 格式一:mailto: 如:ShellExecute(handle,‘open’, ‘mailto:’, nil, nil, SW_SHOWNORMAL);打开新邮件窗口。 格式二:mailto:用户账号@邮件服务器地址 如:ShellExecute(handle, ‘open’,‘ mailto:[email protected]’, nil, nil, SW_SHOWNORMAL);打开新邮件窗口,并自动填入收件人地址。若指定多个收件人地址,则收件人地址之间必须用分号或逗号分隔开(下同)。 格式三:mailto:用户账号@邮件服务器地址?subject=邮件主题&body=邮件正文 如:ShellExecute(handle, ‘open’, ‘ mailto:[email protected]?subject=Hello&Body=This is a test’, nil, nil, SW_SHOWNORMAL);打开新邮件窗口,并自动填入收件人地址、邮件主题和邮件正文。若邮件正文包括多行文本,则必须在每行文本之间加入换行转义字符%0a。 例子(delphi): 在一个应用程序调用c:\Project1.exe; ShellExecute(handle, 'open','c:\Project1.exe','字串内容',nil, SW_SHOWNORMAL); 在Project1.exe里可以调用: procedure TForm1.FormCreate(Sender: TObject); var i:integer; begin for i:=1 to paramcount do if ParamStr(i)<>'' then showmessage(ParamStr(i)); end; 最后的那个参数,为窗口指定可视性方面的一个命令。 请用下述任何一个常数 SW_HIDE 隐藏窗口,活动状态给令一个窗口 SW_MINIMIZE 最小化窗口,活动状态给令一个窗口 SW_RESTORE 用原来的大小和位置显示一个窗口,同时令其进入活动状态 SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态 SW_SHOWMAXIMIZED 最大化窗口,并将其激活 SW_SHOWMINIMIZED 最小化窗口,并将其激活 SW_SHOWMINNOACTIVE 最小化一个窗口,同时不改变活动窗口 SW_SHOWNA 用当前的大小和位置显示一个窗口,不改变活动窗口 SW_SHOWNOACTIVATE 用最近的大小和位置显示一个窗口,同时不改变活动窗口 SW_SHOWNORMAL 与SW_RESTORE相同 让Handle指定的窗体闪烁一次,Flash就是闪烁的意思。可以使用定时器来控制闪烁的频率
1.创建TRegistry对象。为了操作注册表,要创建一个TRegistry对象:ARegistry := TRegistry.Create;
2.释放TRegistry对象。对注册表操作结束后,应释放TRegistry对象所占内存:ARegistry.Destroy。
二、指定要操作的键
操作注册表时,首先应指定操作的主键:先给属性RootKey赋值以指定根键,然后用方法OpenKey来指定要操作的主键名。
1.指定根键(RootKey)。
根键是注册表的入口,也注册表信息的分类,其值可为:
HKEY-CLASSES-ROOT:存储整个系统对象类信息,如ActiveX对象注册、文件关联等信息。
HKEY-CURRENT-USER:存储当前用户的配置信息。为属性RootKey的默认值。
HKEY-LOCAL-MACHINE:存储当前系统的软硬件配置信息。应用程序自己的信息可以存储在该根键下。
HKEY-USERS:存储所有用户通用的配置信息。
还可以是HKEY-CURRENT-CONFIG、HKEY-DYN-DATA。
2.指定要操作的主键。
Function OpenKey(const Key: string; CanCreate: Boolean): Boolean;
Key:主键名,是键名全名中除去根键的部分,如Software。
CanCreate:在指定的主键名不存在时,是否允许创建该主键,True表示允许。
返回值True表示操作成功。
3.关闭当前主键。
在读取或存储信息之后,应及时将关闭当前主键:procedure CloseKey。
三、从注册表中读取信息
Read系列方法从注册表读取指定的信息(字符串、二进制和十六进制),并转换为指定的类型。
1.Read系列方法。
function ReadString(const Name: string): string;
读取一个字符串值,Name为字符串名称。
function ReadInteger(const Name: string): Integer;
读取一个整数值,Name为整数名称。
function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer):Integer;
读取二进制值,Name为二进制值名称,Buffer为接收缓冲区,BufSize为缓冲区大小,返回为实际读取的字节数。
其它方法还有:ReadBool、ReadCurrency、ReadDate、ReadDateTime、ReadFloat、ReadTime。
2.读取信息一例(显示Windows的版本)。
在HKEY-LOCAL-MACHINE下,有三个字符串值Version、VersionNumber和SubVersionNumber,用于记录当前Windows的版本号。
{请在Uses中包含Registry单元}
procedure TForm1.Button1Click(Sender:TObject);
var
ARegistry : TRegistry;
begin
ARegistry := TRegistry.Create;
//建立一个TRegistry实例
with ARegistry do
begin
RootKey := HKEY-LOCAL-MACHINE;//指定根键为HKEY-LOCAL-MACHINE
//打开主键Software
if OpenKey( ′Software′,false ) then
begin
memo1.lines.add('Windows版本:′+ ReadString(′Version′));
memo1.lines.add('Windows版本号:′ + ReadString(′VersionNumber′));
memo1.lines.add(′Windows子版本号:′ + ReadString(′SubVersionNumber′));
end;
CloseKey;//关闭主键
Destroy;//释放内存
end;
end;
四、向注册表中写入信息
Write系列方法将信息转化为指定的类型,并写入注册表。
1.Write系列方法。
procedure WriteString(const Name, value: string);
写入一个字符串值,Name为字符串的名称,value为字符串值。
procedure WriteInteger(const Name: string; value: Integer);
写入一个整数值。
procedure WriteBinaryData(const Name: string; var Buffer; BufSize: Integer);
写入二进制值,Name为二进制值的名称,Buffer为包含二进制值的缓冲区,BufSize为缓冲区大小。
其它方法还有:WriteBool、WriteCurrency、WriteDate、WriteDateTime、WriteFloat、WriteTime。
2.写入信息一例。
下面程序使Delphi随Windows启动而自动运行。
var
ARegistry : TRegistry;
begin
ARegistry := TRegistry.Create;
//建立一个TRegistry实例
with ARegistry do
begin
RootKey:=HKEY-LOCAL-MACHINE;
if OpenKey(′Software′,True) then
WriteString(′delphi′,′C:Files.exe′);
CloseKey;
Destroy;
end;
end;
五、键值维护
除了在注册表中读取、存储外,程序可能还需要增加主键、删除主键、主键改名、数据值改名等。
1.创建新主键:function CreateKey(const Key: string): Boolean。
Key即为主键名,返回值True表示操作成功。
2.删除主键:function DeleteKey(const Key: string): Boolean。
Key即为主键名,返回值True表示操作成功。
3.复制或移动主键:procedure MoveKey(const OldName, NewName: string; Delete: Boolean)。
OldName、NewName分别表示源主键名和目标主键名;Delete表示是否删除源主键,True表示删除,False表示保留。
复制或移动一个主键将复制或移动该子键下的所有数据值和子键内容。
4.判断指定主键是否存在,其下是否有主键,并获取主键名称。
KeyExists用于判断指定主键是否存在:
function KeyExists(const Key: string): Boolean;//返回值为True表示主键存在。
HasSubKeys用于判断指定主键下是否有子键:function HasSubKeys: Boolean;
返回值为True表示主键下有子键。
GetKeyNames用于获取子键名称:procedure GetKeyNames(Strings: TStrings);
Strings用于返回当前主键下各子键的名称。
5.获取主键下的数据值名称:procedure GetvalueNames(Strings: TStrings)。
Strings用于返回当前主键下各数值名称。
如要获取当前系统中的拨号连接名称,可利用获取主键HKEY-USERS
.DEFAULT下的数值名称的方法来进行。
6.判断数值名称存在、数值名称改名。
valueExists用于判断数值名称是否存在:
function valueExists(const Name: string): Boolean;
返回值为True表示数值名称存在。
Renamevalue用于数值名称改名:
procedure Renamevalue(const OldName, NewName: string);
以上是注册表常用操作所对应的TRegistry的方法和属性,其它方法和属性请参见Delphi联机帮助文件。
●getdatainfo方法
function getdatainfo(const valuename:string;var value:tregdatainfo):boolean;
tregdatatype=(rdunknown,rdstring,rdexpandstring,rdexpandstring,rdinterger,rdbinary);
tregdatainfo=record
regdata:tregdatatype;数据类型
datasize:integer;数据大小
end
valuename:和当前键关联的数据值名称
value:返回数据的信息,如为rdstring和rdexpandstring类型,则数据大小包括字符串未尾的空结束字符。如果成功返回true,失败返回false,并且value的值为zeros
rdexpandstring:是一个包含环境变量的字符串;如“%path%”。
●createkey方法
function createkey(const key:string):boolena;
新建一个名为key的键,key可以为绝对的或相对的名字,绝对名用反斜杠“\u8221”开头,相对名是新建一个当前键的子键。新建没有值。成功返回true,否则返回false,如果该键已存在将不产生效果。
●deletekey方法
function deletekey(const key:string):boolean;
删除一个键及相关联的数据,在win95中子键也将被删除,nt中子键必须一个个删除。
●deletevalue方法
function deletevalue (const name:string):boolean;
删除当前键中指定的一个数据值name。
●getdatasize方法
function getdatasize(const valuename:string):integer;
返回当前键中一个指定数值valuename数据的大小。
●getdatatype方法
function getdatatype(const valuename;string):tregdatatype;
返回当前键中一个指定数值valuename数据的类型。
●getkeyinfo方法
function getkeyinfo(var value:tregkeyinfo):boolean;
返回当前键的信息,在于value中。
tregkeyinfo=record
maxsubkeylen:integer;子键名的最长值(字节)
numvalues:integer;键值的数量
maxvaluelen;最长的键值名的长度
filetime:tfiletime;最后一次更改的时间
end;
●getkeynames方法
procedure getkeynames(strings:tsrtings);
返回当前键所有子键的名子列表串。
●getvaluenames
procedure getvaluenames(strings:tstrings);
返回当前键所有键值名的列表串。
●hassubkeys方法
(AdWords)function hassubkeys:boolean;
判断当前键是否有子键,有返回true,否则返回false。
●keyexists方法
function keyexists(const key:string):boolean;
判断指定的键是否存在。
●loadkey方法
function loadkey(const key,filenmae:string):boolean;
在根键下新建
从一个文件中加载注册信息到子键中,文件注册信息中包含数据值名、子键和数据。
loadkey使创建一个键单一化,子键,键值和数据在一人操作中完成,所有这些称为一组,和单独地创建它们不同应用程序可以在一个文件中读取一组数据,这在用户运行中重新设置有特别的用处。
key为要创建子键的名子
filename:为文件的位置,所指定的文件必须为以前用savekey函数或regsavekey api函数所建立的,文件名不能包括扩展名。
●openkey方法
function openkey(const key:string;cancreate:boolean):boolean;
使用该函数可以指定一个键作为当前键,如果键为nil,则当前键将设置为根键。
cancreate决定是否在指定键不存在时创建该键,该函数创建的键的键值将不确定。如果成功地打开或创建,该函数返回true。
●openkeyreadonly方法
function openkeyreadonly(const key: string): boolean;
以只读的方式打开key值指定的键。
●closekey方法
procedure closekey;
当不再使用一个键时应用该方法关闭该键。
●movekey方法
procedure movekey(const oldname, newname: string; delete: boolean);
该方法移动或复制一个键到一个新的位置,并把键的名子改为newname。
在win95/98下该的子键和数据将被一起移动或复制到新的位置,在nt下子键必须用movekey明确的移动或自制。
●读取数据的方法
function readbinarydata(const name: string; var buffer; bufsize: integer):integer;
function readbool(const name: string): boolean;
function readcurrency(const name: string): currency;
function readdate(const name: string): tdatetime;
function readdatetime(const name: string): tdatetime;
function readfloat(const name: string): double;
function readinteger(const name: string): integer;
function readstring(const name: string): string;
function readtime(const name: string): tdatetime;
以上方法从当前主键读取相应数据类型的键值的数据,如果类型不匹配将产生一个异常。
●registryconnect方法
function registryconnect(const uncname: string): boolean;
与另一台计算机的注册表建立连接,在建立连接前应将rootkey属性设为hkey_users或hkey_local_machine。
uncname是另一台计算机的名子。格式如:\computername
假如uncname为nil,将打开本地计算
当然,你可以在"启动"程序组中加入程序的快捷方式,但这样做好像不大明智,因为大多数程序在安装时不会这样做,而通过在注册表增加键值,让WIN 95/98/NT在启动时运行自己的程序.如果打开注册表,找到HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run,就会发
现这个秘密了,原来许多自动运行的程序都在这里.你也可以在这里增加一个键,让你的程序也随着WIN95/98/NT的启动而自己运行,成为WINDOWS下的TSR程序.实现方法如下:
首先,在Uses中加上Registry单元。然后,写下面代码.
{ 将程序strExeFileName置为自动启动 }
function StartUpMyProgram( strPrompt,strExeFileName : string ) : boolean;
var
registerTemp : TRegistry;
begin
registerTemp := TRegistry.Create; //建立一个Registry实例
with registerTemp do
begin
RootKey:=HKEY_LOCAL_MACHINE;//设置根键值为 HKEY_LOCAL_MACHINE
//找到Software\Microsoft\Windows\CurrentVersion\Run
if OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',True) then
//写入自己程序的快捷方式信息
begin
WriteString( strPrompt, strExeFileName );
result := true;
end
else result := false;
//善后处理
CloseKey;
Free;
end;
end;
{ 调用StartUpMyProgram,使Delphi随WINDOWS启动而自动运行 }
procedure TForm1.Button1Click(Sender: TObject);
begin
memo1.lines.add('开始');
if StartUpMyProgram('delphi','C:\Program Files\borland\delphi3\bin\delphi32.exe') then
memo1.lines.add('成功')
else
memo1.lines.add('失败')
end;
应用之二:实现文件关联
当MS WORD安装在你的系统中时,它会把.DOC文件与自己关联,当你双击一个DOC文件,就会启动MS WORD,打开你指定的DOC文件.你也可以把一个文件类型与一个程序关联起来,其秘密还是在注册表中.如果打开注册表,找到HKEY_CLASSES_ROOT,就会发现这里已经有很多文件类型。你也可以在这里增加一个键,建立自己的文件关联.
建立文件关联,一般应有两个步骤:
(1)根据文件类型的扩展名,指定对应的键名(如doc文件对应的键为doc_auto_file),该键及其子键的值,将定义该类型的文件的类型说明和操作(如打开、编辑)说明。
(2)在指定的键名下,建立子键,指明文件类型说明和操作对应的程序信息
例如,我们可以为.DBF文件建立文件关联,其文件类型说明为"xBase数据表",使其打开(Open)文件的操作对应程序C:\Program Files\Borland\DBD\DBD32.EXE.首先,应在注册表的根键HKEY_CLASSES_ROOT下建立一个键,键名为.DBF,默认值为DBF_Auto_File,表示DBF类型文件的关联操作信息记录在键HKEY_CLASSES_ROOT\DBF_Auto_File下;然后,建立键HKEY_CLASSES_ROOT\DBF_Auto_File,并设其默认值为"xBase数据表",表示文件类型说明;再建立键HKEY_CLASSES_ROOT\DBF_Auto_File\Shell\open\command,设置其默认值为C:\Program Files\Borland\DBD\DBD32.EXE %1(其中"%1"为命令行参数),表示打开操作对应的程序信息。
具体实现如下:
同样,在Uses中加上Registry单元,然后,写下面代码.
{ 将文件类型strFileExtension与程序strExeFileName相关联,strDiscription为文件类型说明 }
function AssignToProgram( strFileExtension,strDiscription,strExeFileName : string ) : boolean;
var
registerTemp : TRegistry;
begin
registerTemp := TRegistry.Create; //建立一个Registry实例
with registerTemp do
begin
RootKey:=HKEY_CLASSES_ROOT;//设置根键值为HKEY_CLASSES_ROOTIni文件操作
文本文件操作
二进制文件操作
视频捕获软件开发完全教学
输入框输入
如何产生随机数
文件操作函数
获取文件路径
edit1.text:=extractfiledir(application.ExeName);
edit1.text:=extractfilepath(application.ExeName);
这个是获取自身目录的函数,两函数不同的是一个路径后带有"\",一个没有
如果要获取打开文件的路径,使用opendialog控件(在dialogs控件组下):
begin
if opendialog1.Execute then
edit1.text:=opendialog1.FileName ;
//在文本框显示路径
end;调用外部可执行文件
调用office组件
创建和调用Dll
DLL中封装窗体
利用dll封装类
Ping操作
串口通信的实现
COM技术
在Delphi中调用dll
多线程编程
调试技巧
数据结构和算法
链表应用
小窍门
屏幕分辨率的获得
让电脑发出“嘣”声
在窗口中拖动控件
TDBlistbox控件显示字段信息
关闭-重启计算机
窗口保持在最前
原型如下:
BOOL SetWindowPos(
HWND hWnd, // 窗口句柄
HWND hWndInsertAfter, // 基于的某窗口的句柄,或为注1中某项
int X, // 水平位置
int Y, // 垂直位置
int cx, // 宽度
int cy, // 高度
UINT uFlags // 安置操作标志 注2
);
注1.HWND_BOTTOM、HWND_NOTOPMOST、HWND_TOP、HWND_TOPMOST
注2.指定“SWP_NOZORDER”标志 (忽略hWndInsertAfter句柄参数)
界面设计(可用模块)
界面加强控件
确实使用起来是相当的方便。
1>添加一个空的imagelist控件至form上
2>分别添加ActionManager,ActionMainMenuBar,ActionToolBar控件至form上
并将ActionManager的image属性和imagelist关联!
3>然后就可以开始了:) 先在ActionManager控件上双击或右击->customise,弹出edit窗口。
4>然后就可以在右边的actions灰色listbox中右击鼠标,接着我们展示一下他们的强大功能吧!
5>弹出菜单上的new standard action...,存放了常用的标准action序列。选择,记住这里可以按shift键多选。添加至actionmanager中。
这是如果存在imagelist的话,他们会自动添加标准的小图标。
6>从ActionManager的edit对话框中直接拖放这些action
到ActionMainMenuBar,ActionToolBar上吧... 闪屏
窗口停泊
制作闪烁窗体
活动控件制作
控件的锚标志使用
窗体背景色渐变
字体旋转
为对象蒙上面纱
资源管理器的制作
动态建表
窗体透明度设置
树形显示的程序界面
不可移动窗体
动画形式的程序界面
窗体边框加粗、变更颜色
增加图片、工具栏、状态条、窗口切换菜单……
>>菜单应用
在系统菜单中添加菜单项
动态加入/删除菜单&带历史信息的菜单
>>工具栏设计
带背景的工具栏
>>导航菜单设计
带导航菜单的主界面
图像化的导航界面
网络编程
套接字
套接字是网络通信的基本构件,提供了不同主机间进程双向通信的端点,如同电话,只有当一方拨通另一方时,双方方能建立对话,而套接字正好比双方的电话。通过Sockets编程,程序可以跳过复杂的网络底层协议和结构,直接编制与平台无关的应用程序。随着Internet的广泛应用,Sockets已逐渐成为网络编程的通用接口。
1、MicrosoftVisualBasic实现
MicrosoftVisualBasic提供了用于WindowsSockets编程的可用控件--Winsock控件。该控件为用户提供了访问TCP和UDP网络的极其方便的途径。并且适用于MicrosoftAccess、VisualBasic、VisualC++和VisualFoxPro等多种可视化环境。通过Winsock控件编制C/S程序,程序员无须了解TCP或低级WinsockAPIs调用实现的细节,如用户无须考虑网络字节顺序与本机字接顺序便可直接进行数据的传送。用该控件实现网间进程通信极其方便。
随着Internet的逐步兴起,Sockets编程必将成为流行的网络编程接口之一。也许您会发问:ISO的OSI模型又是何等地位呢?笔者的观点是:ISO的OSI模型必将成为网络应用的统一界面,Sockets接口的广泛应用则为OSI模型开拓了更广泛的应用前景Winsock Api函数
用于初始化Winsock
[声明]
int WSAStarup(WORD wVersionRequested,LPWSADATA lpWSAData);
[参数]
wVersionRequested - 要求使用Winsock的最低版本号
lpWSAData - Winsock的详细资料
[返回值]
当函数成功调用时返回0
失败时返回非0的值
用于生成socket(soket Descriptor)
[声明]
SOCKET socket(int af,int type,int protocol);
[参数]
af - 地址家族(通常使用:AF_INET)
type - socket的种类
SOCK_STREAM : 用于TCP协议
SOCK_DGRAM : 用于UDP协议
protocol - 所使用的协议
[返回值]
当函数成功调用时返回一个新的SOCKET(Socket Descriptor)
失败时返回INVALID_SOCKET.
把好象"xxx.xxx.xxx.xxx"的10进制的IP地址转换为32位整数表示方法
[声明]
unsigned long inet_addr ( const char FAR *cp );
[参数]
cp - 指向用"xxx.xxx.xxx.xxx"的10进制来表示的IP地址字符串的指针
[返回值]
当函数成功调用时返回用32位整数表示的IP地址(按网络字节排列顺序)
失败时返回INADDR_NONE.
可以从主机名获取主机资料.
[声明]
struct hostent FAR * gethostbyname ( const char FAR *name );
[参数]
name - 指向主机名字符串的指针
[返回值]
当函数成功调用时返回主机信息
失败时返回NULL(空值)
指定本地IP地址所使用的端口号时候使用
[声明]
int bind ( SOCKET s , const struct sockaddr FAR *addr , int namelen );
[参数]
s - 指向用Socket函数生成的Socket Descriptor
addr - 指向Socket地址的指针
namelen - 该地址的长度.
[返回值]
当函数成功调用时返回0
调用失败时返回 SOCKET_ERROR
用于与服务器建立连接,发出连接请求,必须在参数中指定服务器的IP地址和端口号
[声明]
int connect (SOCKET s , const struct sockaddr FAR *name , int namelen );
[参数]
s - 指向用Socket函数生成的Socket Descriptor
name - 指向服务器地址的指针
namelen - 该地址的长度.
[返回值]
当函数成功调用时返回0
调用失败时返回 SOCKET_ERROR
可以用于调查一个或多个SOCKET的状态.
[声明]
int select ( int nfds , fd_set FAR *readfds , fd_set FAR *writefds , fd_set FAR *exceptfds , const struct timeval FAR *timeout );
[参数]
nfds - 在WINDOWS SOCKET API 中该参数可以忽略,通常赋予NILL值
readfds - 由于接受的SOCKET设备的指针
writefds - 用于发送数据的SOCKET设备的指针
exceptfds - 检查错误的状态
timeout - 超时设定
[返回值]
返回大于0的值时,表示与条件相符的SOCKET数
返回0表示超时
失败时返回SOCKET_ERROR
利用Socket进行接受数据.
[声明]
int recv ( SOCKET s , char FAR *buf , int len , int flags );
[参数]
s - 指向用Socket函数生成的Socket Descriptor
buf - 接受数据的缓冲区(数组)的指针
len - 缓冲区的大小
flag - 调用方式(MSG_PEEK 或 MSG_OOB)
[返回值]
成功时返回收到的字节数.
如果连接被中断则返回0
失败时返回 SOCKET_ERROR
利用Socket进行发送数据.
[声明]
int sendto ( SOCKET s , const char FAR *buf , int len , int flags , const struct sockaddr FAR *to , int token );
[参数]
s - 指向用Socket函数生成的Socket Descriptor
buf - 接受数据的缓冲区(数组)的指针
len - 缓冲区的大小
flag - 调用方式(MSG_DONTROUTE , MSG_OOB)
to - 指向发送方SOCKET地址的指针
token - 发送方SOCKET地址的大小
[返回值]
成功时返回已经发送的字节数.
失败时返回SOCKET_ERROR获取本地IP
检测计算机是否上网
经验谈
数据库设计
编程操作
概念区分
名词解释
什么是回调函数
理解回调函数!
程序在调用一个函数(function)时(通常指api).相当于程序(program)呼叫(Call)了一个函数(function)关系表示如下:
call(调用)
program --------------------→ dll
程序在调用一个函数时,将自己的函数的地址作为参数传递给程序调用的函数时(那么这个自己的函数称回调函数).需要回调函数的 DLL 函数往往是一些必须重复执行某些操作的函数.关系表示如下:
call(调用)
program --------------------→ dll
↑ ¦
¦_______________________________¦
callback(回调)
当你调用的函数在传递返回值给回调函数时,你就可以利用回调函数来处理或完成一定的操作。至于如何定义自己的回调函数,跟具体使用的API函数有关,很多不同类别的回调函数有各种各样的参数,有关这些参数的描述一般在帮助中有说明回调函数的参数和返回值等.其实简单说回调函数就是你所写的函数满足一定条件后,被DLL调用!
也有这样的说法(比较容易理解):
回调函数就好像是一个中断处理函数,系统在符合你设定的条件时自动调用。为此,你需要做三件事:
1. 声明;
2. 定义;
3. 设置触发条件,就是在你的函数中把你的回调函数名称转化为地址作为一个参数,以便于DLL调用。动态链接库
动态链接是相对于静态链接而言的。所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。换句话说,函数和过程的代码就在程序的exe文件中,该文件包含了运行时所需的全部代码。当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源。而动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。仅当应用程序被装入内存开始运行时,在Windows的管理下,才在应用程序与相应的DLL之间建立链接关系。当要执行所调用DLL中的函数时,根据链接产生的重定位信息,Windows才转去执行DLL中相应的函数代码。
一般情况下,如果一个应用程序使用了动态链接库,Win32系统保证内存中只有DLL的一份复制品,这是通过内存映射文件实现的。DLL首先被调入Win32系统的全局堆栈,然后映射到调用这个DLL的进程地址空间。在Win32系统中,每个进程拥有自己的32位线性地址空间,如果一个DLL被多个进程调用,每个进程都会收到该DLL的一份映像。与16位Windows不同,在Win32中DLL可以看作是每个进程自己的代码。
二、动态链接库的优点
1. 共享代码、资源和数据
使用DLL的主要目的就是为了共享代码,DLL的代码可以被所有的Windows应用程序共享。
2. 隐藏实现的细节
DLL中的例程可以被应用程序访问,而应用程序并不知道这些例程的细节。
3. 拓展开发工具如Delphi的功能
由于DLL是与语言无关的,因此可以创建一个DLL,被C++、VB或任何支持动态链接库的语言调用。这样如果一种语言存在不足,就可以通过访问另一种语言创建的DLL来弥补。
三、动态链接库的实现方法
1. Load-time Dynamic Linking
这种用法的前提是在编译之前已经明确知道要调用DLL中的哪几个函数,编译时在目标文件中只保留必要的链接信息,而不含DLL函数的代码;当程序执行时,利用链接信息加载DLL函数代码并在内存中将其链接入调用程序的执行空间中,其主要目的是便于代码共享。
2. Run-time Dynamic Linking
这种方式是指在编译之前并不知道将会调用哪些DLL函数,完全是在运行过程中根据需要决定应调用哪个函数,并用LoadLibrary和GetProcAddress动态获得DLL函数的入口地址。
教你认识动态链接库DLL文件
DLL是Dynamic Link Library的缩写,意为动态链接库。在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可有多个DLL文件,一个DLL文件也可能被几个应用程序所共用,这样的DLL文件被称为共享DLL文件。DLL文件一般被存放在C:WindowsSystem目录下。
1、如何了解某应用程序使用哪些DLL文件
右键单击该应用程序并选择快捷菜单中的“快速查看”命令,在随后出现的“快速查看”窗口的“引入表”一栏中你将看到其使用DLL文件的情况。
2、如何知道DLL文件被几个程序使用
运行Regedit,进入HKEY_LOCAL_MACHINESoftwareMicrosrftWindowsCurrent-
VersionSharedDlls子键查看,其右边窗口中就显示了所有DLL文件及其相关数据,其中数据右边小括号内的数字就说明了被几个程序使用,(2)表示被两个程序使用,(0)则表示无程序使用,可以将其删除。
3、如何解决DLL文件丢失的情况
有时在卸载文件时会提醒你删除某个DLL文件可能会影响其他应用程序的运行。所以当你卸载软件时,就有可能误删共享的DLL文件。一旦出现了丢失DLL文件的情况,如果你能确定其名称,可以在Sysbckup(系统备份文件夹)中找到该DLL文件,将其复制到System文件夹中。如果这样不行,在电脑启动时又总是出现“***dll文件丢失……”的提示框,你可以在“开始/运行”中运行Msconfig,进入系统配置实用程序对话框以后,单击选择“System.ini”标签,找出提示丢失的DLL文件,使其不被选中,这样开机时就不会出现错误提示了。继承-重载-多态性
你还有个哥哥,也从你老爸那里学会了手艺。
你和你哥哥各自把你老爸的手艺发扬光大,成为了各自有特色新手艺,这就叫多态。
纯粹胡扯,这哪是重载?这是继承!“子承父业”你没听说这句话?
重载是指对一个功能函数的输入参数进行改变,但保持他的函数名不变,而且能完成不同的功能,就叫对此函数进行重载!
重载其实就是多态性的一种表现!虚拟方法和抽象方法
而抽象方法是虚拟方法中的特例,指完全没有具体实现的虚拟方法.Delphi备查常量资料
键盘的ASC码
回车键: VK_RETURN (13)
TAB键: VK_TAB (9)
Caps Lock键: VK_CAPITAL (20)
Shift键: VK_SHIFT ($10)
Ctrl键: VK_CONTROL (17)
Alt键: VK_MENU (18)
空格键: VK_SPACE ($20/32)
退格键: VK_BACK (8)
左徽标键: VK_LWIN (91)
右徽标键: VK_LWIN (92)
鼠标右键快捷键:VK_APPS (93)
Home键: VK_HOME (36)
Page Up: VK_PRIOR (33)
PageDown: VK_NEXT (34)
End键: VK_END (35)
Delete键: VK_DELETE (46)
方向键(↑): VK_UP (38)
方向键(→): VK_RIGHT (39)
方向键(↓): VK_DOWN (40)
F1键: VK_F1 (112)
F2键: VK_F2 (113)
F3键: VK_F3 (114)
F4键: VK_F4 (115)
F5键: VK_F5 (116)
F6键: VK_F6 (117)
F7键: VK_F7 (118)
F8键: VK_F8 (119)
F9键: VK_F9 (120)
F10键: VK_F10 (121)
F11键: VK_F11 (122)
F12键: VK_F12 (123)
Num Lock键: VK_NUMLOCK (144)
小键盘0: VK_NUMPAD0 (96)
小键盘1: VK_NUMPAD0 (97)
小键盘2: VK_NUMPAD0 (98)
小键盘3: VK_NUMPAD0 (99)
小键盘4: VK_NUMPAD0 (100)
小键盘5: VK_NUMPAD0 (101)
小键盘6: VK_NUMPAD0 (102)
小键盘7: VK_NUMPAD0 (103)
小键盘8: VK_NUMPAD0 (104)
小键盘9: VK_NUMPAD0 (105)
小键盘.: VK_DECIMAL (110)
小键盘*: VK_MULTIPLY (106)
小键盘+: VK_MULTIPLY (107)
小键盘-: VK_SUBTRACT (109)
小键盘/: VK_DIVIDE (111)
Pause Break键: VK_PAUSE (19)
Scroll Lock键: VK_SCROLL (145)Delphi颜色常量
进制转换
var
j: integer;
s: string;
begin
j := i;
s := ' ';
while j >= 2 do
begin
if (j mod 2) = 1 then
begin
s := '1' + s;
j := j div 2;
end
else
begin
s := '0' + s;
j := j div 2;
end;
end;
s := chr(ord('0') + j) + s;
result := s;
end;
var
i, j, t: integer;
s: char;
begin
t := 1;
j := length(k);
j := 0 + (ord(k[j]) - ord('0')) * t;
;
for i := length(k) - 1 downto 1 do
begin
s := k[i];
t := t * 2;
j := j + ((ord(s) - ord('0')) * t);
end;
result := j;
end;
begin
result := InttoHex(i, 4);
end;
begin
result := StrtoInt('$' + k);
end;
begin
result := OcttoBin(HextoOct(k));
end;
begin
result := Octtohex(BintoOct(k));
end; Delphi快捷键
CTRL+SHIFT+C 编写申明或者补上函数
CTRL+SHIFT+↑(↓) 在过程、函数、事件内部, 可跳跃到相应的过程、函数、事件的定义(在INTERFACE和IMPLEMENTATION之间来回切换)
CTRL+SHIFT+G 插入GUID
CTRL+END 将光标移至文件尾
CTRL+PAGEDOWN 将光标移至本屏的最后一行,屏幕不滚动
CTRL+PAGEUP 将光标移至本屏的第一行,屏幕不滚动
CTRL+J (弹出DELPHI语句提示窗口,选择所需语句将自动完成一条语句)代码模板
SHIFT+ALT+F11 显示对象列表窗口
F12 切换EDITOR/FORM
CTRL+F12 打开某个单元文件
SHIFT+F12 打开某个窗体
CTRL+K+E(F) 标识符变小(大)写
CTRL+K+O(N) 选中的变小(大)写
CTRL+O+U 切换选择块的大小写
SHIFT+鼠标左键 先选中任一控件,按键后可选中窗体
ALT+鼠标左键 可以块选代码,用来删除对齐的重复代码非常有用
CTRL+E 快速选择(呵呵,试试吧,很好玩的)
在属性窗口按TAB键将光标移动到属性名区,键入属性名的开头字母可快速定位到该属性
F4 运行到光标处
F5 设置断点
F7 步进式调试同时追踪进入子过程
F8 步进式调试不进入子过程
F9 运行
CTRL+F9 编译
CTRL+B BUFFER LIST窗口
CTRL+F2 停止正在调试的程序
CTRL+F3 弹出CALL STACK窗口
CTRL+F5 添加览视变量
CTRL+F7 计算窗口
SHIFT+F8 调试时弹出CPU窗口
CTRL+BACKSPACE 后退删除一个词,直到遇到一个分割符
CTRL+T 删除光标右边的一个单词
CTRL+SHIFT+Y 删除光标之后至本行末尾之间的文本
ALT+[(]) 查找上(下)一个对应的标识符
CTRL+ENTER 定位到单元文件
CTRL+↑(↓) 向上(下)滚动屏幕,光标跟随滚动不出本屏
ALT+G 跳到某行 (G:go)
CTRL+S 保存
SHIFT+CTRL+S 保存所有
CTRL+F4 等于FILE菜单中的CLOSE项
CTRL+I 插入TAB
CTRL+L 继续查找
CTRL+N 同ENTER键,但光标位置保持不变
CTRL+SHIFT+E 显示EXPLORER
CTRL+SHIFT+F11 打开工程设置窗口
CTRL+TAB 在INSPECTOR中切换PROPERTIES页和EVENTS页
CTRL+SHIFT+N 定义(取消)书签N
CTRL+N 跳到书签N
CTRL+箭头 以1像素单位更改所选控件位置
SHIFT+箭头 以1像素单位更改所选控件大小
ALT+F11 Use某个单元
SHIFT+F10 等于鼠标右键(WINDOWS快捷键)。
SHITF+箭头 选择文本编译错误速查
常用图标路径
基本算法(用 PASCAL 描述)
求两数的最大公约数
function gcd(a,b:integer):integer;
begin
if b=0 then gcd:=a
else gcd:=gcd (b,a mod B);
end;
求两数的最小公倍数
function lcm(a,b:integer):integer;
begin
if a< b then swap(a,B);
lcm:=a;
while lcm mod b >0 do inc(lcm,a);
end;
素数的求法
A.小范围内判断一个数是否为质数:
function prime (n: integer): Boolean;
var I: integer;
begin
for I:=2 to trunc(sqrt(n)) do
if n mod I=0 then begin
prime:=false; exit;
end;
prime:=true;
end;
B.判断longint范围内的数是否为素数(包含求50000以内的素数表):
procedure getprime;
var
i,j:longint;
p:array[1..50000] of boolean;
begin
fillchar(p,sizeof(p),true);
p[1]:=false;
i:=2;
while i< 50000 do begin
if p[i] then begin
j:=i*2;
while j< 50000 do begin
p[j]:=false;
inc(j,i);
end;
end;
inc(i);
end;
l:=0;
for i:=1 to 50000 do
if p[i] then begin
inc(l);pr[l]:=i;
end;
end;{getprime}
function prime(x:longint):integer;
var i:integer;
begin
prime:=false;
for i:=1 to l do
if pr[i] >=x then break
else if x mod pr[i]=0 then exit;
prime:=true;
end;{prime}
2.
3.
4.求最小生成树
A.Prim算法:
procedure prim(v0:integer);
var
lowcost,closest:array[1..maxn] of integer;
i,j,k,min:integer;
begin
for i:=1 to n do begin
lowcost[i]:=cost[v0,i];
closest[i]:=v0;
end;
for i:=1 to n-1 do begin
{寻找离生成树最近的未加入顶点k}
min:=maxlongint;
for j:=1 to n do
if (lowcost[j]< min) and (lowcost[j]< >0) then begin
min:=lowcost[j];
k:=j;
end;
lowcost[k]:=0; {将顶点k加入生成树}
{生成树中增加一条新的边k到closest[k]}
{修正各点的lowcost和closest值}
for j:=1 to n do
if cost[k,j]< lwocost[j] then begin
lowcost[j]:=cost[k,j];
closest[j]:=k;
end;
end;
end;{prim}
B.Kruskal算法:(贪心)
按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
function find(v:integer):integer; {返回顶点v所在的集合}
var i:integer;
begin
i:=1;
while (i< =n) and (not v in vset[i]) do inc(i);
if i< =n then find:=i else find:=0;
end;
procedure kruskal;
var
tot,i,j:integer;
begin
for i:=1 to n do vset[i]:=[i];{初始化定义n个集合,第I个集合包含一个元素I}
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针}
sort;
{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度}
while p >0 do begin
i:=find(e[q].v1);j:=find(e[q].v2);
if i< >j then begin
inc(tot,e[q].len);
vset[i]:=vset[i]+vset[j];vset[j]:=[];
dec(p);
end;
inc(q);
end;
writeln(tot);
end;
5.最短路径
A.标号法求解单源点最短路径:
var
a:array[1..maxn,1..maxn] of integer;
b:array[1..maxn] of integer; {b[i]指顶点i到源点的最短路径}
mark:array[1..maxn] of boolean;
procedure bhf;
var
best,best_j:integer;
begin
fillchar(mark,sizeof(mark),false);
mark[1]:=true; b[1]:=0;{1为源点}
repeat
best:=0;
for i:=1 to n do
If mark[i] then {对每一个已计算出最短路径的点}
for j:=1 to n do
if (not mark[j]) and (a[i,j] >0) then
if (best=0) or (b[i]+a[i,j]< best) then begin
best:=b[i]+a[i,j]; best_j:=j;
end;
if best >0 then begin
b[best_j]:=best;mark[best_j]:=true;
end;
until best=0;
end;{bhf}
B.Floyed算法求解所有顶点对之间的最短路径:
procedure floyed;
begin
for I:=1 to n do
for j:=1 to n do
if a[I,j] >0 then p[I,j]:=I else p[I,j]:=0; {p[I,j]表示I到j的最短路径上j的前驱结点}
for k:=1 to n do {枚举中间结点}
for i:=1 to n do
for j:=1 to n do
if a[i,k]+a[j,k]< a[i,j] then begin
a[i,j]:=a[i,k]+a[k,j];
p[I,j]:=p[k,j];
end;
end;
C. Dijkstra 算法:
类似标号法,本质为贪心算法。
var
a:array[1..maxn,1..maxn] of integer;
b,pre:array[1..maxn] of integer; {pre[i]指最短路径上I的前驱结点}
mark:array[1..maxn] of boolean;
procedure dijkstra(v0:integer);
begin
fillchar(mark,sizeof(mark),false);
for i:=1 to n do begin
d[i]:=a[v0,i];
if d[i]< >0 then pre[i]:=v0 else pre[i]:=0;
end;
mark[v0]:=true;
repeat {每循环一次加入一个离1集合最近的结点并调整其他结点的参数}
min:=maxint; u:=0; {u记录离1集合最近的结点}
for i:=1 to n do
if (not mark[i]) and (d[i]< min) then begin
u:=i; min:=d[i];
end;
if u< >0 then begin
mark[u]:=true;
for i:=1 to n do
if (not mark[i]) and (a[u,i]+d[u]< d[i]) then begin
d[i]:=a[u,i]+d[u];
pre[i]:=u;
end;
end;
until u=0;
end;
D.计算图的传递闭包
Procedure Longlink;
Var
T:array[1..maxn,1..maxn] of boolean;
Begin
Fillchar(t,sizeof(t),false);
For k:=1 to n do
For I:=1 to n do
For j:=1 to n do T[I,j]:=t[I,j] or (t[I,k] and t[k,j]);
End;
6.0-1背包问题
数据结构:
w[i]:第i个背包的重量;
p[i]:第i个背包的价值;
(1)0-1背包: 每个背包只能使用一次或有限次(可转化为一次):
A.求最多可放入的重量。
NOIP2001 装箱问题
有一个箱子容量为v(正整数,o≤v≤20000),同时有n个物品(o≤n≤30),每个物品有一个体积 (正整数)。要求从 n 个物品中,任取若千个装入箱内,使箱子的剩余空间为最小。
l 搜索方法
procedure search(k,v:integer); {搜索第k个物品,剩余空间为v}
var i,j:integer;
begin
if v< best then best:=v;
if v-(s[n]-s[k-1]) >=best then exit; {s[n]为前n个物品的重量和}
if k< =n then begin
if v >w[k] then search(k+1,v-w[k]);
search(k+1,v);
end;
end;
l DP
F[I,j]为前i个物品中选择若干个放入使其体积正好为j的标志,为布尔型。
实现:将最优化问题转化为判定性问题
F[I,j]=f[i-1,j-w[i]] (w[I]< =j< =v) 边界:f[0,0]:=true.
For I:=1 to n do
For j:=w[I] to v do F[I,j]:=f[I-1,j-w[I]];
优化:当前状态只与前一阶段状态有关,可降至一维。
F[0]:=true;
For I:=1 to n do begin
F1:=f;
For j:=w[I] to v do
If f[j-w[I]] then f1[j]:=true;
F:=f1;
End;
B.求可以放入的最大价值。
F[I,j]=
C.求恰好装满的情况数。
(2)每个背包可使用任意次:
A.求最多可放入的重量。
状态转移方程为
f[I,j]=max{f[i-w[j]
B.求可以放入的最大价值。
USACO 1.2 Score Inflation
进行一次竞赛,总时间T固定,有若干种可选择的题目,每种题目可选入的数量不限,每种题目有一个ti(解答此题所需的时间)和一个si(解答此题所得的分数),现要选择若干题目,使解这些题的总时间在T以内的前提下,所得的总分最大,求最大的得分。
*易想到:
f[i,j] = max { f [i- k*w[j], j-1] + k*v[j] } (0< =k< = i div w[j])
其中f[i,j]表示容量为i时取前j种背包所能达到的最大值。
*优化:
Begin
FillChar(problem,SizeOf(problem),0);
Assign(Input,'inflate.in');
Reset(Input);
Readln(M,N);
For i:=1 To N Do
With problem[i] Do
Readln(point,time);
Close(Input);
FillChar(f,SizeOf(f),0);
For i:=1 To M Do
For j:=1 To N Do
If i-problem[j].time >=0 Then
Begin
t:=problem[j].point+f[i-problem[j].time];
If t >f[i] Then f[i]:=t;
End;
Assign(Output,'inflate.out');
Rewrite(Output);
Writeln(f[M]);
Close(Output);
End.
C.求恰好装满的情况数。
Ahoi2001 Problem2
求自然数n本质不同的质数和的表达式的数目。
思路一,生成每个质数的系数的排列,在一一测试,这是通法。
procedure try(dep:integer);
var i,j:integer;
begin
cal; {此过程计算当前系数的计算结果,now为结果}
if now >n then exit; {剪枝}
if dep=l+1 then begin {生成所有系数}
cal;
if now=n then inc(tot);
exit;
end;
for i:=0 to n div pr[dep] do begin
xs[dep]:=i;
try(dep+1);
xs[dep]:=0;
end;
end;
思路二,递归搜索效率较高
procedure try(dep,rest:integer);
var i,j,x:integer;
begin
if (rest< =0) or (dep=l+1) then begin
if rest=0 then inc(tot);
exit;
end;
for i:=0 to rest div pr[dep] do
try(dep+1,rest-pr[dep]*i);
end;
思路三:可使用动态规划求解
USACO1.2 money system
V个物品,背包容量为n,求放法总数。
转移方程:
Procedure update;
var j,k:integer;
begin
c:=a;
for j:=0 to n do
if a[j] >0 then
for k:=1 to n div now do
if j+now*k< =n then inc(c[j+now*k],a[j]);
a:=c;
end;
{main}
begin
read(now); {读入第一个物品的重量}
i:=0; {a[i]为背包容量为i时的放法总数}
while i< =n do begin
a[i]:=1; inc(i,now); end; {定义第一个物品重的整数倍的重量a值为1,作为初值}
for i:=2 to v do
begin
read(now);
update; {动态更新}
end;
writeln(a[n]);
7.排序算法
A.快速排序:
procedure sort(l,r:integer);
var i,j,mid:integer;
begin
i:=l;j:=r; mid:=a[(l+r) div 2]; {将当前序列在中间位置的数定义为中间数}
repeat
while a[i]< mid do inc(i); {在左半部分寻找比中间数大的数}
while mid< a[j] do dec(j);{在右半部分寻找比中间数小的数}
if i< =j then begin {若找到一组与排序目标不一致的数对则交换它们}
swap(a[i],a[j]);
inc(i);dec(j); {继续找}
end;
until i >j;
if l< j then sort(l,j); {若未到两个数的边界,则递归搜索左右区间}
if i< r then sort(i,r);
end;{sort}
B.插入排序:
procedure insert_sort(k,m:word); {k为当前要插入的数,m为插入位置的指针}
var i:word; p:0..1;
begin
p:=0;
for i:=m downto 1 do
if k=a[i] then exit;
repeat
If k >a[m] then begin
a[m+1]:=k; p:=1;
end
else begin
a[m+1]:=a[m]; dec(m);
end;
until p=1;
end;{insert_sort}
l 主程序中为:
a[0]:=0;
for I:=1 to n do insert_sort(b[I],I-1);
C.选择排序:
procedure sort;
var i,j,k:integer;
begin
for i:=1 to n-1 do begin
k:=i;
for j:=i+1 to n do
if a[j]< a[k] then k:=j; {找出a[I]..a[n]中最小的数与a[I]作交换}
if k< >i then begin
a[0]:=a[k];a[k]:=a[i];a[i]:=a[0];
end;
end;
end;
D. 冒泡排序
procedure sort;
var i,j,k:integer;
begin
for i:=n downto 1 do
for j:=1 to i-1 do
if a[j] >a[i] then begin
a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
end;
end;
E.堆排序:
procedure sift(i,m:integer);{调整以i为根的子树成为堆,m为结点总数}
var k:integer;
begin
a[0]:=a[i]; k:=2*i;{在完全二叉树中结点i的左孩子为2*i,右孩子为2*i+1}
while k< =m do begin
if (k< m) and (a[k]< a[k+1]) then inc(k);{找出a[k]与a[k+1]中较大值}
if a[0]< a[k] then begin a[i]:=a[k];i:=k;k:=2*i; end
else k:=m+1;
end;
a[i]:=a[0]; {将根放在合适的位置}
end;
procedure heapsort;
var
j:integer;
begin
for j:=n div 2 downto 1 do sift(j,n);
for j:=n downto 2 do begin
swap(a[1],a[j]);
sift(1,j-1);
end;
end;
F. 归并排序
{a为序列表,tmp为辅助数组}
procedure merge(var a:listtype; p,q,r:integer);
{将已排序好的子序列a[p..q]与a[q+1..r]合并为有序的tmp[p..r]}
var I,j,t:integer;
tmp:listtype;
begin
t:=p;i:=p;j:=q+1;{t为tmp指针,I,j分别为左右子序列的指针}
while (t< =r) do begin
if (i< =q){左序列有剩余} and ((j >r) or (a[i]< =a[j])) {满足取左边序列当前元素的要求}
then begin
tmp[t]:=a[i]; inc(i);
end
else begin
tmp[t]:=a[j];inc(j);
end;
inc(t);
end;
for i:=p to r do a[i]:=tmp[i];
end;{merge}
procedure merge_sort(var a:listtype; p,r: integer); {合并排序a[p..r]}
var q:integer;
begin
if p< >r then begin
q:=(p+r-1) div 2;
merge_sort (a,p,q);
merge_sort (a,q+1,r);
merge (a,p,q,r);
end;
end;
{main}
begin
merge_sort(a,1,n);
end.
G.基数排序
思想:对每个元素按从低位到高位对每一位进行一次排序
8.高精度计算
A.
B.
C.
D.
9.树的遍历顺序转换
A. 已知前序中序求后序
procedure Solve(pre,mid:string);
var i:integer;
begin
if (pre='') or (mid='') then exit;
i:=pos(pre[1],mid);
solve(copy(pre,2,i),copy(mid,1,i-1));
solve(copy(pre,i+1,length(pre)-i),copy(mid,i+1,length(mid)-i));
post:=post+pre[1]; {加上根,递归结束后post即为后序遍历}
end;
B.已知中序后序求前序
procedure Solve(mid,post:string);
var i:integer;
begin
if (mid='') or (post='') then exit;
i:=pos(post[length(post)],mid);
pre:=pre+post[length(post)]; {加上根,递归结束后pre即为前序遍历}
solve(copy(mid,1,I-1),copy(post,1,I-1));
solve(copy(mid,I+1,length(mid)-I),copy(post,I,length(post)-i));
end;
C.已知前序后序求中序
function ok(s1,s2:string):boolean;
var i,l:integer; p:boolean;
begin
ok:=true;
l:=length(s1);
for i:=1 to l do begin
p:=false;
for j:=1 to l do
if s1[i]=s2[j] then p:=true;
if not p then begin ok:=false;exit;end;
end;
end;
procedure solve(pre,post:string);
var i:integer;
begin
if (pre='') or (post='') then exit;
i:=0;
repeat
inc(i);
until ok(copy(pre,2,i),copy(post,1,i));
solve(copy(pre,2,i),copy(post,1,i));
midstr:=midstr+pre[1];
solve(copy(pre,i+2,length(pre)-i-1),copy(post,i+1,length(post)-i-1));
end;
10.求图的弱连通子图(DFS)
procedure dfs ( now,color: integer);
begin
for i:=1 to n do
if a[now,i] and c[i]=0 then begin
c[i]:=color;
dfs(I,color);
end;
end;
11.拓扑排序
寻找一数列,其中任意连续p项之和为正,任意q 项之和为负,若不存在则输出NO.
12.进制转换
A.整数任意正整数进制间的互化
NOIP1996数制转换
设字符串A$的结构为: A$='mp'
其中m为数字串(长度< =20),而n,p均为1或2位的数字串(其中所表达的内容在2-10之间)
程序要求:从键盘上读入A$后(不用正确性检查),将A$中的数字串m(n进制)以p进制的形式输出.
例如:A$='48< 10 >8'
其意义为:将10进制数48,转换为8进制数输出.
输出结果:48< 10 >=60< 8 >
B.实数任意正整数进制间的互化
C.负数进制:
NOIP2000
设计一个程序,读入一个十进制数的基数和一个负进制数的基数,并将此十进制数转换为此负 进制下的数:-R∈{-2,-3,-4,....-20}
13.全排列与组合的生成
排列的生成:(1..n)
procedure solve(dep:integer);
var
i:integer;
begin
if dep=n+1 then begin writeln(s);exit; end;
for i:=1 to n do
if not used[i] then begin
s:=s+chr(i+ord('0'));used[i]:=true;
solve(dep+1);
s:=copy(s,1,length(s)-1); used[i]:=false;
end;
end;
组合的生成(1..n中选取k个数的所有方案)
procedure solve(dep,pre:integer);
var
i:integer;
begin
if dep=k+1 then begin writeln(s);exit; end;
for i:=1 to n do
if (not used[i]) and (i >pre) then begin
s:=s+chr(i+ord('0'));used[i]:=true;
solve(dep+1,i);
s:=copy(s,1,length(s)-1); used[i]:=false;
end;
end;
14 递推关系
计算字串序号模型
USACO1.2.5 StringSobits
长度为N (N< =31)的01串中1的个数小于等于L的串组成的集合中找出按大小排序后的第I个01串。
数字划分模型
*NOIP2001数的划分
将整数n分成k份,且每份不能为空,任意两种分法不能相同(不考虑顺序)。
d[0,0]:=1;
for p:=1 to n do
for i:=p to n do
for j:=k downto 1 do inc(d[i,j],d[i-p,j-1]);
writeln(d[n,k]);
*变形1:考虑顺序
d[ i, j] : = d [ i-k, j-1] (k=1..i)
*变形2:若分解出来的每个数均有一个上限m
d[ i, j] : = d [ i-k, j-1] (k=1..m)
15.算符优先法求解表达式求值问题
const maxn=50;
var
s1:array[1..maxn] of integer; {s1为数字栈}
s2:array[1..maxn] of char; {s2为算符栈}
t1,t2:integer; {栈顶指针}
procedure calcu;
var
x1,x2,x:integer;
p:char;
begin
p:=s2[t2]; dec(t2);
x2:=s1[t1]; dec(t1);
x1:=s1[t1]; dec(t1);
case p of
'+':x:=x1+x2;
'-':x:=x1-x2;
'*':x:=x1*x2;
'/':x:=x1 div 2;
end;
inc(t1);s1[t1]:=x;
end;
procedure work;
var c:char;v:integer;
begin
t1:=0;t2:=0;
read©;
while c< >';' do
case c of
'+','-': begin
while (t2 >0) and (s2[t2]< >'(') do calcu;
inc(t2);s2[t2]:=c;
read©;
end ;
'*','/':begin
if (t2 >0) and ((s2[t2]='*') or (s2[t2]='/')) then calcu;
inc(t2);s2[t2]:=c;
read©;
end;
'(':begin inc(t2); s2[t2]:=c; read©; end;
')':begin
while s2[t2]< >'(' do calcu;
dec(t2); read©;
end;
'0'..'9':begin
v:=0;
repeat
v:=10*v+ord©-ord('0');
read©;
until (c< '0') or (c >'9');
inc(t1); s1[t1]:=v;
end;
end;
while t2 >0 do calcu;
writeln(s1[t1]);
end;
16.查找算法
折半查找
function binsearch(k:keytype):integer;
var low,hig,mid:integer;
begin
low:=1;hig:=n;
mid:=(low+hig) div 2;
while (a[mid].key< >k) and (low< =hig) do begin
if a[mid].key >k then hig:=mid-1
else low:=mid+1;
mid:=(low+hig) div 2;
end;
if low >hig then mid:=0;
binsearch:=mid;
end;
树形查找
二叉排序树:每个结点的值都大于其左子树任一结点的值而小于其右子树任一结点的值。
查找
function treesrh(k:keytype):pointer;
var q:pointer;
begin
q:=root;
while (q< >nil) and (q^.key< >k) do
if k< q^.key then q:=q^.left
else q:=q^.right;
treesrh:=q;
end;
17.KMP算法
18.贪心
*会议问题
(1) n个活动每个活动有一个开始时间和一个结束时间,任一时刻仅一项活动进行,求满足活动数最多的情况。
解:按每项活动的结束时间进行排序,排在前面的优先满足。
(2)会议室空闲时间最少。
(3)每个客户有一个愿付的租金,求最大利润。
(4)共R间会议室,第i个客户需使用i间会议室,费用相同,求最大利润。
附录1 常用技巧
1.带权中位数
我国蒙古大草原上有N(N是不大于100的自然数)个牧民定居点P1(X1,Y1)、P2(X2,Y2)、 …Pn(Xn,Yn),相应地有关权重为Wi,现在要求你在大草原上找一点P(Xp,Yp),使P点到任 一点Pi的距离Di与Wi之积之和为最小。
即求 D=W1*D1+W2*D2+…+Wi*Di+…+Wn*Dn 有最小值
结论:对x与y两个方向分别求解带权中位数,转化为一维。
设最佳点p为点k,则点k满足:
令W为点k到其余各点的带权距离之和,则
sigema( i=1 to k-1) Wi*Di < = W/2
sigema( i=k+1 to n) Wi*Di < = W/2
同时满足上述两式的点k即为带权中位数。
2.求一序列中连续子序列的最大和
begin
maxsum:=-maxlongint;
sum:=0;
for i:=1 to n do begin
inc(sum,data[i]);
if sum >maxsum then maxsum:=sum;
if sum< 0 then sum:=0;
end;
writeln(maxsum);
end;delphi常用数值算法源代码
线程优先级及属性
遇到的delphi系统函数/过程
函数
API函数使用
ShellExecute使用详解(DELPHI版)
FlashWindow
flashwindow(handle,true):开始闪烁
flashwindow(handle,false):停止闪烁