<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_jiangyuxuan</title><subtitle type="text"/><id>http://feed.cnblogs.com/blog/u/15628/rss</id><updated>2012-03-22T17:06:35Z</updated><author><name>江宇旋</name><uri>http://www.cnblogs.com/jiangyuxuan/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jiangyuxuan/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/15628/rss"/><entry><id>http://www.cnblogs.com/jiangyuxuan/archive/2012/03/23/2413031.html</id><title type="text">在Delphi中如何获得SQL中存储过程的返回值?</title><summary type="text">示例存储过程：create procedure proc_loginusername varchar(20),password varchar(20)asdeclare @result intselect @result=count(*) from loginuser where user=@username and pass=@passwordif @result=0return 0return 1goDelphi代码：var ret:integer;...... with ADOStoredProc1 do begin Close; ProcedureName:='proc_log</summary><published>2012-03-22T16:54:00Z</published><updated>2012-03-22T16:54:00Z</updated><author><name>江宇旋</name><uri>http://www.cnblogs.com/jiangyuxuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/23/2413031.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/23/2413031.html"/><content type="html">&lt;div class="cnt" id="blog_text"&gt;&lt;p&gt;示例存储过程：&lt;br /&gt;create procedure proc_login&lt;br /&gt;username varchar(20),&lt;br /&gt;password varchar(20)&lt;br /&gt;as&lt;br /&gt;declare @result int&lt;br /&gt;select @result=count(*) from loginuser where user=@username and pass=@password&lt;br /&gt;if @result=0&lt;br /&gt;return 0&lt;br /&gt;return 1&lt;br /&gt;go&lt;br /&gt;&lt;br /&gt;Delphi代码：&lt;br /&gt;var ret:integer;&lt;br /&gt;......&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; with ADOStoredProc1 do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Close;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProcedureName:='proc_login';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Parameters.Clear;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Parameters.Refresh;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Parameters.ParamByName('@username').Value:= Edit1.text;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Parameters.ParamByName('@password').Value:= Edit2.text;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExecProc;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret:= Parameters.ParamByName('@return_value').Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ret=1 //用户名密码匹配&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //你想要的操作&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;/p&gt;&lt;p&gt;示例二&lt;/p&gt;&lt;p&gt;在delphi中取存储过程的返回值&lt;br /&gt;&amp;nbsp;&amp;nbsp; Close;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SQL.Clear;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SQL.Text:='declare @ReturnCount int exec Pr_SelStockHead '''+StockNo+''',@ReturnCount output select @ReturnCount';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; open;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CountNO:=fields[0].value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxtxtdtNameCSHYH.Text:=IntToStr(CountNO);&lt;br /&gt;在sql语句里面 如果有返回值的话,可以是用return 返回,,其他的都是参数返回,如果取参数的话 从 Parameters[1].Value 开始,如果取return 的返回值 要用Parameters[0].Value&lt;/p&gt;&lt;p&gt;调用存储过程的方法，用adodataset控件&lt;br /&gt;function TfrmPower_Cut.HasNewPowerCutInfo: Boolean;&lt;br /&gt;begin&lt;br /&gt;Result := False;&lt;br /&gt;with spPower_Cut do //spPower_Cut为Tadostoredproc控件&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Close;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProcedureName := 'p_Has_PowerCut_Info';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; with Parameters do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Clear;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Refresh;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParamByName(&lt;a&gt;'@BiggestID').Direction&lt;/a&gt; := pdInputOutput;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParamByName(&lt;a&gt;'@BiggestID').Value&lt;/a&gt; := FPower_Cut_ID_Refresh;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParamByName(&lt;a&gt;'@NoProcess').Direction&lt;/a&gt; := pdInputOutput;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParamByName(&lt;a&gt;'@NoProcess').Value&lt;/a&gt; := FNoProcess;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParamByName(&lt;a&gt;'@IsPassTimeAndNoProc').Direction&lt;/a&gt; := pdInputOutput;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParamByName(&lt;a&gt;'@IsPassTimeAndNoProc').Value&lt;/a&gt; := FIsPassTimeAndNoProc;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParamByName(&lt;a&gt;'@IsNearestTime').Direction&lt;/a&gt; := pdInputOutput;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParamByName(&lt;a&gt;'@IsNearestTime').Value&lt;/a&gt; := FIsNearestTime;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParamByName(&lt;a&gt;'@IsDelete').Direction&lt;/a&gt; := pdInputOutput;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParamByName(&lt;a&gt;'@IsDelete').Value&lt;/a&gt; := FIsNearestTime;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ParamByName(&lt;a&gt;'@Hour').Value&lt;/a&gt; := 3;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Prepared;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExecProc;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Parameters[0].Value &amp;lt;&amp;gt; FPower_Cut_ID_Refresh then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FPower_Cut_ID_Refresh := Parameters[1].Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := True;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Parameters[2].Value &amp;lt;&amp;gt; FNoProcess then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FNoProcess := Parameters[2].Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := True;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Parameters[3].Value &amp;lt;&amp;gt; FIsPassTimeAndNoProc then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FIsPassTimeAndNoProc := Parameters[3].Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := True;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Parameters[4].Value &amp;lt;&amp;gt; FIsNearestTime then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FIsNearestTime := Parameters[4].Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := True;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Parameters[5].Value &amp;lt;&amp;gt; FIsDelete then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FIsDelete := Parameters[5].Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := True;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on e: Exception do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ShowMessage(e.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;end;&lt;br /&gt;end;&lt;br /&gt;存储过程&lt;br /&gt;/*&lt;br /&gt;功能: 判断数据库内是否有新的呼叫中心停电信息&lt;br /&gt;参数: @BiggestID 客户端最大的记录ID,如果小于当前表中的ID,则返回最大的ID,客户端据此判断是否刷新&lt;br /&gt;返回值: 无&lt;br /&gt;*/&lt;br /&gt;ALTER procedure p_Has_PowerCut_Info @BiggestID bigint=0 output, @NoProcess int=0 output, &lt;br /&gt;@IsPassTimeAndNoProc int=0 output, @IsNearestTime int=0 output, @IsDelete int=0 output, @Hour int=3 as&lt;br /&gt;begin&lt;br /&gt;declare @tmp_ID bigint,@tmp_NoProcess int&lt;br /&gt;select @tmp_ID=Power_Cut_ID from Power_Cut &lt;br /&gt;if (@@error=0) and (@@rowcount&amp;gt;0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if @tmp_id&amp;gt;@BiggestID &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set @BiggestID=@tmp_ID&lt;br /&gt;select @tmp_NoProcess=count(*) from Power_Cut where PC_ProcType=0&lt;br /&gt;if (@@error=0) and (@@rowcount&amp;gt;0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set @NoProcess=@tmp_NoProcess&lt;br /&gt;--超过发送时间未处理&lt;br /&gt;select @IsPassTimeAndNoProc=count(case when (getdate()&amp;gt;PC_StartTime and PC_ProcType=0) then 1 end) from Power_Cut &lt;br /&gt;--距离发送时间还有3小时未处理&lt;br /&gt;select @IsNearestTime=count(case when (DATEDIFF(minute, getdate(), PC_StartTime)&amp;gt;=0 and DATEDIFF(minute, getdate(), PC_StartTime)&amp;lt;@Hour*60 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; and PC_ProcType=0) then 1 end) from Power_Cut&lt;br /&gt;select @IsDelete=count(*) from Power_Cut where PC_State=2&lt;br /&gt;return @BiggestID&lt;br /&gt;end&lt;br /&gt;return 返回的是正确或错误的标志,比如 100: 成功 0: 失败(未知原因) 1: 参数错误 2: .... 然后参数里面返回具体需要的数据&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;img src="http://www.cnblogs.com/jiangyuxuan/aggbug/2413031.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/23/2413031.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jiangyuxuan/archive/2012/03/07/2382838.html</id><title type="text">Delphi StringGrid使用全书</title><summary type="text">StringGrid行列的增加和删除typeTExCell = class(TStringGrid)publicprocedure DeleteRow(ARow: Longint);procedure DeleteColumn(ACol: Longint);procedure InsertRow(ARow: LongInt);procedure InsertColumn(ACol: LongInt);end;procedure TExCell.InsertColumn(ACol: Integer);beginColCount :=ColCount +1;MoveColumn(ColCount-</summary><published>2012-03-06T16:02:00Z</published><updated>2012-03-06T16:02:00Z</updated><author><name>江宇旋</name><uri>http://www.cnblogs.com/jiangyuxuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/07/2382838.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/07/2382838.html"/><content type="html">&lt;p&gt;StringGrid行列的增加和删除&lt;br /&gt;type&lt;br /&gt;TExCell = class(TStringGrid)&lt;/p&gt;&lt;p&gt;public&lt;br /&gt;procedure DeleteRow(ARow: Longint);&lt;br /&gt;procedure DeleteColumn(ACol: Longint);&lt;br /&gt;procedure InsertRow(ARow: LongInt);&lt;br /&gt;procedure InsertColumn(ACol: LongInt);&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;procedure TExCell.InsertColumn(ACol: Integer);&lt;br /&gt;begin&lt;br /&gt;ColCount :=ColCount +1;&lt;br /&gt;MoveColumn(ColCount-1, ACol);&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;procedure TExCell.InsertRow(ARow: Integer);&lt;br /&gt;begin&lt;br /&gt;RowCount :=RowCount +1;&lt;br /&gt;MoveRow(RowCount-1, ARow);&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;procedure TExCell.DeleteColumn(ACol: Longint);&lt;br /&gt;begin&lt;br /&gt;MoveColumn(ACol, ColCount -1);&lt;br /&gt;ColCount := ColCount - 1;&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;procedure TExCell.DeleteRow(ARow: Longint);&lt;br /&gt;begin&lt;br /&gt;MoveRow(ARow, RowCount - 1);&lt;br /&gt;RowCount := RowCount - 1;&lt;br /&gt;end; &lt;/p&gt;&lt;p&gt;&lt;p&gt;&lt;br /&gt;如何编写使StringGrid中的一列具有Check功能，和CheckBox效果一样&lt;br /&gt;unit Unit1;&lt;/p&gt;&lt;p&gt;interface&lt;/p&gt;&lt;p&gt;uses&lt;br /&gt;Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids;&lt;/p&gt;&lt;p&gt;type&lt;br /&gt;TForm1 = class(TForm)&lt;br /&gt;grid: TStringGrid;&lt;br /&gt;procedure FormCreate(Sender: TObject);&lt;br /&gt;procedure gridDrawCell(Sender: TObject; ACol, ARow: Integer;&lt;br /&gt;Rect: TRect; State: TGridDrawState);&lt;br /&gt;procedure gridClick(Sender: TObject);&lt;/p&gt;&lt;p&gt;private&lt;br /&gt;{ Private declarations }&lt;/p&gt;&lt;p&gt;public&lt;br /&gt;{ Public declarations }&lt;/p&gt;&lt;p&gt;end;&lt;/p&gt;&lt;p&gt;var&lt;br /&gt;Form1: TForm1;&lt;br /&gt;fcheck,fnocheck:tbitmap;&lt;/p&gt;&lt;p&gt;implementation&lt;/p&gt;&lt;p&gt;{$R *.DFM}&lt;/p&gt;&lt;p&gt;procedure TForm1.FormCreate(Sender: TObject);&lt;br /&gt;var&lt;br /&gt;i:SmallInt;&lt;br /&gt;bmp:TBitmap;&lt;br /&gt;begin&lt;br /&gt;FCheck:= TBitmap.Create;&lt;br /&gt;FNoCheck:= TBitmap.Create;&lt;br /&gt;bmp:= TBitmap.create;&lt;br /&gt;try&lt;br /&gt;　 bmp.handle := LoadBitmap( 0, PChar(OBM_CHECKBOXES ));&lt;br /&gt;　 With FNoCheck Do Begin&lt;br /&gt; width := bmp.width div 4;&lt;br /&gt; height := bmp.height div 3;&lt;br /&gt; canvas.copyrect( canvas.cliprect, bmp.canvas, canvas.cliprect );&lt;br /&gt;　 End;&lt;br /&gt;With FCheck Do Begin&lt;br /&gt;　 width := bmp.width div 4;&lt;br /&gt;　 height := bmp.height div 3;&lt;br /&gt;　 canvas.copyrect(canvas.cliprect, bmp.canvas, rect( width, 0, 2*width, height ));&lt;br /&gt;End;&lt;br /&gt;finally&lt;br /&gt;　 bmp.free&lt;br /&gt;end;&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;procedure TForm1.gridDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);&lt;br /&gt;begin&lt;br /&gt;if not (gdFixed in State) then&lt;br /&gt;　 with TStringGrid(Sender).Canvas do&lt;br /&gt;begin&lt;br /&gt;　 brush.Color:=clWindow;&lt;br /&gt;　 FillRect(Rect);&lt;br /&gt;　 if Grid.Cells[ACol,ARow]='yes' then&lt;br /&gt; Draw( (rect.right + rect.left - FCheck.width) div 2, (rect.bottom + rect.top - FCheck.height) div 2, FCheck )&lt;br /&gt;　 else&lt;br /&gt; Draw( (rect.right + rect.left - FCheck.width) div 2, (rect.bottom + rect.top - FCheck.height) div 2, FNoCheck );&lt;br /&gt;end;&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;procedure TForm1.gridClick(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;if grid.Cells[grid.col,grid.row]='yes' then&lt;br /&gt;　 grid.Cells[grid.col,grid.row]:='no'&lt;br /&gt;else&lt;br /&gt;　 grid.Cells[grid.col,grid.row]:='yes';&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;end. &lt;/p&gt;&lt;p&gt;&lt;p&gt;StringGrid组件Cells内容分行显示在Tstringgrid.ondrawcell事件中&lt;/p&gt;&lt;p&gt;DrawText(StringGrid1.Canvas.Handle,pchar(StringGrid1.Cells[Acol,Arow]),Length(StringGrid1.Cells[Acol,Arow]),Rect,DT_WORDBREAK or DT_LEFT);&lt;/p&gt;&lt;p&gt;可以实现文字换行！ &lt;/p&gt;&lt;p&gt;&lt;p&gt;在StringGrid怎样制作只读的列在 OnSelectCell事件处理程序中,加入: (所有的列均设成可修改的)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;if Col mod 2 = 0 then&lt;br /&gt;　 grd.Options := grd.Options + [goEditing]&lt;br /&gt;else&lt;br /&gt;　 grd.Options := grd.Options - [goEditing]; &lt;/p&gt;&lt;p&gt;&lt;p&gt;stringgrid从文本读入的问题（Save/Load a TStringGrid to/from a file?）stringgrid从文本读入的问题&lt;/p&gt;&lt;p&gt;// Save a TStringGrid to a file&lt;br /&gt;procedure SaveStringGrid(StringGrid: TStringGrid; const FileName: TFileName);&lt;br /&gt;var&lt;br /&gt;f: TextFile;&lt;br /&gt;i, k: Integer;&lt;br /&gt;begin&lt;br /&gt;AssignFile(f, FileName);&lt;br /&gt;Rewrite(f);&lt;br /&gt;with StringGrid do&lt;br /&gt;begin&lt;br /&gt;　 // Write number of Columns/Rows&lt;br /&gt;　 Writeln(f, ColCount);&lt;br /&gt;　 Writeln(f, RowCount);&lt;br /&gt;　 // loop through cells&lt;br /&gt;　 for i := 0 to ColCount - 1 do&lt;br /&gt; for k := 0 to RowCount - 1 do&lt;br /&gt;　 Writeln(F, Cells[i, k]);&lt;br /&gt;end;&lt;br /&gt;CloseFile(F);&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;// Load a TStringGrid from a file&lt;br /&gt;procedure LoadStringGrid(StringGrid: TStringGrid; const FileName: TFileName);&lt;br /&gt;var&lt;br /&gt;f: TextFile;&lt;br /&gt;iTmp, i, k: Integer;&lt;br /&gt;strTemp: String;&lt;br /&gt;begin&lt;br /&gt;AssignFile(f, FileName);&lt;br /&gt;Reset(f);&lt;br /&gt;with StringGrid do&lt;br /&gt;begin&lt;br /&gt;　 // Get number of columns&lt;br /&gt;　 Readln(f, iTmp);&lt;br /&gt;　 ColCount := iTmp;&lt;br /&gt;　 // Get number of rows&lt;br /&gt;　 Readln(f, iTmp);&lt;br /&gt;　 RowCount := iTmp;&lt;br /&gt;　 // loop through cells &amp;amp; fill in values&lt;br /&gt;　 for i := 0 to ColCount - 1 do&lt;br /&gt; for k := 0 to RowCount - 1 do&lt;br /&gt; begin&lt;br /&gt;　 Readln(f, strTemp);&lt;br /&gt;　 Cells[i, k] := strTemp;&lt;br /&gt; end;&lt;br /&gt;　 end;&lt;br /&gt;CloseFile(f);&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;// Save StringGrid1 to 'c:.txt':&lt;br /&gt;procedure TForm1.Button1Click(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;SaveStringGrid(StringGrid1, 'c:.txt');&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;// Load StringGrid1 from 'c:.txt':&lt;br /&gt;procedure TForm1.Button2Click(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;LoadStringGrid(StringGrid1, 'c:.txt');&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;*******************************************&lt;/p&gt;&lt;p&gt;打开一个已有的文本文件,并将内容放到stringgrid中,文本行与stringgrid行一致; &lt;br /&gt;在文本中遇到空格则放入下一cells.&lt;br /&gt;搞定！注意，我只写了一个空格间隔的，你自己修改一下splitstring可以用多个空格分隔！&lt;/p&gt;&lt;p&gt;procedure TForm1.Button1Click(Sender: TObject);&lt;br /&gt;var&lt;br /&gt;aa,bb:tstringlist;&lt;br /&gt;i:integer;&lt;br /&gt;begin&lt;br /&gt;aa:=tstringlist.Create;&lt;br /&gt;bb:=tstringlist.Create;&lt;br /&gt;aa.LoadFromFile('c:.txt');&lt;br /&gt;for i:=0 to aa.Count-1 do&lt;br /&gt;begin&lt;br /&gt;　 bb:=SplitString(aa.Strings[i],' ');&lt;br /&gt;　 stringgrid1.Rows[i]:=bb;&lt;br /&gt;end;&lt;br /&gt;aa.Free;&lt;br /&gt;bb.Free;&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;其中splitstring为：&lt;/p&gt;&lt;p&gt;function SplitString(const source,ch:string):tstringlist;&lt;br /&gt;var&lt;br /&gt;temp:string;&lt;br /&gt;i:integer;&lt;br /&gt;begin&lt;br /&gt;result:=tstringlist.Create;&lt;br /&gt;temp:=source;&lt;br /&gt;i:=pos(ch,source);&lt;br /&gt;while i&amp;lt;&amp;gt;0 do&lt;br /&gt;begin&lt;br /&gt;　 result.Add(copy(temp,0,i-1));&lt;br /&gt;　 delete(temp,1,i);&lt;br /&gt;　 i:=pos(ch,temp);&lt;br /&gt;end;&lt;br /&gt;result.Add(temp);&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;&lt;p&gt;StringGrid组件Cells内容对齐&lt;/p&gt;&lt;p&gt;在StringGrid的DrawCell事件中添加类似的代码就可以了：&lt;/p&gt;&lt;p&gt;VAR&lt;br /&gt;vCol, vRow : LongInt;&lt;br /&gt;begin&lt;br /&gt;vCol := ACol; vRow := ARow;&lt;br /&gt;WITH Sender AS TStringGrid, Canvas DO&lt;br /&gt;　 IF vCol = 2 THEN BEGIN ///对于第2列设置为右对齐&lt;br /&gt; SetTextAlign(Handle, TA_RIGHT);&lt;br /&gt; FillRect(Rect);&lt;br /&gt; TextRect(Rect, Rect.RIGHT-2, Rect.Top+2, Cells[vCol, vRow]);&lt;br /&gt;　 END;&lt;br /&gt;end; &lt;/p&gt;&lt;p&gt;&lt;p&gt;当我将StringGird的options属性中包含goRowSelect项时每当我选中StringGrid中一行， 则选中行用深蓝色显示，我想将深蓝色改为其他颜色应怎样该？当我将StringGird的options属性中包含goRowSelect项时每当我选中StringGrid中一行， 则选中行用深蓝色显示，我想将深蓝色改为其他颜色应怎样该？&lt;br /&gt;procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;&lt;br /&gt;Rect: TRect; State: TGridDrawState);&lt;br /&gt;begin&lt;br /&gt;With StringGrid1 do&lt;br /&gt;begin&lt;br /&gt;　 If　(ARow= Krow) and not (acol = 0) then&lt;br /&gt;　 begin&lt;br /&gt;　Canvas.Brush.Color :=clYellow;// ClBlue;&lt;br /&gt;　Canvas.FillRect(Rect);&lt;br /&gt;　Canvas.font.color:=ClBlack;&lt;br /&gt;　Canvas.TextOut(rect.left , rect.top, cells[acol, arow]);&lt;br /&gt;　 end;&lt;br /&gt;end;&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,&lt;br /&gt;ARow: Integer; var CanSelect: Boolean);&lt;br /&gt;begin&lt;br /&gt;krow := Arow;　//*&lt;br /&gt;kcol := Acol;&lt;br /&gt;end;　&lt;/p&gt;&lt;p&gt;注意：必须把变量KROW的值初始为1或其他不为0的值，否则如果锁定第一行的话，第一行的颜色将被自设颜色取代，而锁定行不会被重画。&lt;/p&gt;&lt;p&gt;&lt;p&gt;怎么改变StringGrid控件某一列的背景和某一列的只读属性,StringGrid控件标题栏的对齐.怎么改变StringGrid控件某一列的背景和某一列的只读属性,StringGrid控件标题栏的对齐.&lt;br /&gt;请参考以下代码：&lt;br /&gt;在OnDrawCell事件中处理背景色。程序如下：&lt;br /&gt;//将第二列背景变为红色。&lt;br /&gt;procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;&lt;br /&gt;Rect: TRect; State: TGridDrawState);&lt;br /&gt;begin&lt;br /&gt;if not((acol=1) and (arow&amp;gt;=stringgrid1.fixedrows)) then exit;&lt;br /&gt;with stringgrid1 do&lt;br /&gt;begin&lt;br /&gt;　 canvas.Brush.color:=clRed;&lt;br /&gt;　 canvas.FillRect(Rect);&lt;br /&gt;　 canvas.TextOut(rect.left+2,rect.top+2,cells[acol,arow])&lt;br /&gt;end;&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;//加入如下代码,那么StringGrid的第四列就只读了.其他列非只读&lt;br /&gt;procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);&lt;br /&gt;begin&lt;br /&gt;with StringGrid1 do begin&lt;br /&gt;　 if ACol = 4 then&lt;br /&gt; Options := Options - [goEditing]&lt;br /&gt;　 else Options := Options + [goEditing];&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);&lt;br /&gt;var&lt;br /&gt;dx,dy:byte;&lt;br /&gt;begin&lt;br /&gt;if (acol = 4) and not (arow = 0) then&lt;br /&gt;　 with stringgrid1 do&lt;br /&gt;　 begin&lt;br /&gt; canvas.Brush.color := clYellow;&lt;br /&gt; canvas.FillRect(Rect);&lt;br /&gt; canvas.font.color := clblue;&lt;br /&gt; dx:=2;//调整此值，控制字在网格中显示的水平位置&lt;br /&gt; dy:=2;//调整此值，控制字在网格中显示的垂直位置&lt;br /&gt; canvas.TextOut(rect.left+dx , rect.top+dy , cells[acol, arow]);&lt;br /&gt;　 end;&lt;br /&gt;//控制标题栏的对齐&lt;br /&gt;if (arow = 0) then&lt;br /&gt;　 with stringgrid1 do&lt;br /&gt;　 begin&lt;br /&gt; canvas.Brush.color := clbtnface;&lt;br /&gt; canvas.FillRect(Rect);&lt;br /&gt; dx := 12; //调整此值，控制字在网格中显示的水平位置&lt;br /&gt; dy := 5; //调整此值，控制字在网格中显示的垂直位置&lt;br /&gt; canvas.TextOut(rect.left + dx, rect.top + dy, cells[acol, arow]);&lt;br /&gt;　 end;&lt;br /&gt;end;　 &lt;/p&gt;&lt;p&gt;&lt;p&gt;在stringGrid中使用回车键模拟TAB键切换单元格的功能实现......procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);&lt;br /&gt;label&lt;br /&gt;nexttab;&lt;br /&gt;begin&lt;br /&gt;if key=#13 then&lt;br /&gt;begin&lt;br /&gt;　 key:=#0;&lt;br /&gt;　 nexttab:&lt;br /&gt;　 if (stringgrid1.Col begin&lt;br /&gt;　 stringgrid1.Col:=stringgrid1.Col+1;&lt;br /&gt; end&lt;br /&gt;　 else&lt;br /&gt;　 begin&lt;br /&gt; if stringgrid1.Row&amp;gt;=stringgrid1.RowCount-1 then&lt;br /&gt;　 stringgrid1.RowCount:=stringgrid1.rowCount+1;&lt;br /&gt; stringgrid1.Row:=stringgrid1.Row+1;&lt;br /&gt; stringgrid1.Col:=0;&lt;br /&gt; goto nexttab;&lt;br /&gt;　 end;&lt;br /&gt;end;&lt;br /&gt;end;&lt;br /&gt;.........　 &lt;/p&gt;&lt;p&gt;&lt;p&gt;stringgrid如何清空&lt;br /&gt;with StringGrid1 do for I := 0 to ColCount - 1 do Cols[I].Clear; &lt;/p&gt;&lt;p&gt;&lt;p&gt;选中某单元格,然后在该单元格中修改-&amp;gt; 选中某单元格,然后在该单元格中修改设置属性:&lt;br /&gt;　 StringGrid1.Options:=StringGrid1.Options+[goEditing]; &lt;/p&gt;&lt;p&gt;&lt;p&gt;让记录在StringGrid中分页显示在Uses中加入： ADOInt &lt;br /&gt;//首先设定PageSize，取出PageCount&lt;br /&gt;procedure TForm1.Button1Click(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;ADoquery1.Recordset.PageSize :=spinedit1.Value;&lt;br /&gt;Edit1.Text := IntToStr(ADoquery1.Recordset.PageCount);&lt;br /&gt;ShowData(spinedit2.Value);&lt;br /&gt;end; &lt;/p&gt;&lt;p&gt;//然后将AbsolutePage的数据乾坤大挪移到StringGrid1中 &lt;br /&gt;procedure TForm1.ShowData(page:integer);&lt;br /&gt;var&lt;br /&gt;iRow, iCol, iCount : Integer;&lt;br /&gt;rs : ADOInt.Recordset;&lt;br /&gt;begin&lt;br /&gt;ADoquery1.Recordset.AbsolutePage:=Page;&lt;br /&gt;Currpage:=page;　&lt;br /&gt;iRow := 0;&lt;br /&gt;iCol := 1;&lt;br /&gt;stringgrid1.Cells[iCol, iRow] := 'FixedCol1';&lt;br /&gt;Inc(iCol);&lt;br /&gt;stringgrid1.Cells[iCol, iRow] := 'FixedCol2';&lt;br /&gt;Inc(iRow);&lt;br /&gt;Dec(iCol);&lt;br /&gt;rs := adoquery1.Recordset;&lt;br /&gt;for iCount := 1 to SpinEdit1.Value do &lt;br /&gt;begin&lt;br /&gt;　 stringgrid1.Cells[iCol, iRow] := rs.Fields.Get_Item('FieldName1').Value;&lt;br /&gt;　 Inc(iCol);&lt;br /&gt;　 stringgrid1.Cells[iCol, iRow] := rs.Fields.Get_Item('FieldName1').Value;&lt;br /&gt;　 Inc(iRow);&lt;br /&gt;　 Dec(iCol);&lt;br /&gt;　 rs.MoveNext;&lt;br /&gt;end;&lt;br /&gt;　&lt;br /&gt;//上一页 &lt;br /&gt;procedure TForm1.Button2Click(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;If (CurrPage)&amp;lt;&amp;gt;1 then&lt;br /&gt;　 ShowData(CurrPage-1);&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;//下一页&lt;br /&gt;procedure TForm1.Button3Click(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;If CurrPage&amp;lt;&amp;gt;ADoquery1.Recordset.PageCount then&lt;br /&gt;　 ShowData(CurrPage+1);&lt;br /&gt;end; &lt;/p&gt;&lt;p&gt;&lt;p&gt;打印StringGrid的程序源码这段代码没有看懂，但是可能有的朋友需要，所以共享一下子 ：）&lt;br /&gt;procedure TForm1.SpeedButton11Click(Sender: TObject);&lt;br /&gt;Var&lt;br /&gt;Index_R ,ALeft: Integer;&lt;br /&gt;Index : Integer;&lt;br /&gt;begin&lt;br /&gt;StringGrid_File('D:\AAA.TXT');&lt;br /&gt;if Not LinkTextFile then&lt;br /&gt;begin&lt;br /&gt;　 ShowMessage('失败');&lt;br /&gt;　 Exit;&lt;br /&gt;end;&lt;br /&gt;//&lt;br /&gt;QuickRep1.DataSet := ADOTable1;&lt;br /&gt;Index_R := ReSize(StringGrid1.Width);&lt;br /&gt;ALeft := 13;&lt;br /&gt;Create_Title(TitleBand1,ALeft,24,HeaderControl1.Sections.Items[0].Width,20,&lt;br /&gt;HeaderControl1.Sections[0].Text,taLeftJustify);&lt;br /&gt;with Create_QRDBText(DetailBand1,ALeft,8,StringGrid1.ColWidths[0],20,&lt;br /&gt;StringGrid1.Font,taLeftJustify) do&lt;br /&gt;begin&lt;br /&gt;　 DataSet := ADOTable1;&lt;br /&gt;　 DataField := ADOTable1.Fields[0].DisplayName;&lt;br /&gt;end;&lt;br /&gt;ALeft := ALeft + StringGrid1.ColWidths[0] * Index_R + Index_R;&lt;br /&gt;For Index := 1 to ADOTable1.FieldCount - 1 do&lt;br /&gt;begin&lt;br /&gt;　 Create_VLine(TitleBand1,ALeft - 13,16,1,40);&lt;br /&gt;　 Create_Title(TitleBand1,ALeft,24,HeaderControl1.Sections.Items[Index].Width,20,&lt;br /&gt; HeaderControl1.Sections[Index].Text,taLeftJustify);&lt;br /&gt;　 Create_VLine(DetailBand1,ALeft - 13,-1,1,31);&lt;br /&gt;　 with Create_QRDBText(DetailBand1,ALeft ,8,StringGrid1.ColWidths[Index] * Index_R,20,&lt;br /&gt;StringGrid1.Font,taLeftJustify) do&lt;br /&gt;　 begin&lt;br /&gt; DataSet := ADOTable1;&lt;br /&gt; DataField := ADOTable1.Fields[Index].DisplayName;&lt;br /&gt;　 end;&lt;br /&gt;　 ALeft := ALeft + StringGrid1.ColWidths[Index] *　Index_R + Index_R;&lt;br /&gt;end;&lt;br /&gt;QuickRep1.Preview;&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;function TForm1.ReSize(AGridWidth: Integer): Integer;&lt;br /&gt;begin&lt;br /&gt;Result := Trunc(718 / AGridWidth);&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;function TForm1.StringGrid_File(AFileName: String): Boolean;&lt;br /&gt;var&lt;br /&gt;StrValue : String;&lt;br /&gt;Index : Integer;&lt;br /&gt;ACol , ARow : Integer;&lt;br /&gt;AFileValue : System.TextFile;&lt;br /&gt;begin&lt;br /&gt;StrValue := '';&lt;br /&gt;Try&lt;br /&gt;　 AssignFile(AFileValue , AFileName);&lt;br /&gt;　 ReWrite(AFileValue);&lt;br /&gt;　 StrValue := HeaderControl1.Sections[0].Text;&lt;br /&gt;　 For Index := 1 to HeaderControl1.Sections.Count - 1 do&lt;br /&gt; StrValue := StrValue + ',' + HeaderControl1.Sections[Index].Text;&lt;br /&gt;　 Writeln(AFileValue,StrValue);&lt;br /&gt;　 StrValue := '';&lt;br /&gt;　 For　ARow := 0 To StringGrid1.RowCount - 1 do&lt;br /&gt;　 begin&lt;br /&gt; StrValue := '';&lt;br /&gt; StrValue := StringGrid1.Cells[0,ARow];&lt;br /&gt; For ACol := 1 To StringGrid1.ColCount - 1 do&lt;br /&gt; begin&lt;br /&gt;　 StrValue := StrValue + ', ' + StringGrid1.Cells[ACol,ARow];&lt;br /&gt; end;&lt;br /&gt; Writeln(AFileValue,StrValue);&lt;br /&gt;　 end;&lt;br /&gt;Finally&lt;br /&gt;　 CloseFile(AFileValue);&lt;br /&gt;end;&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;function TForm1.LinkTextfile: Boolean;&lt;br /&gt;begin&lt;br /&gt;Result := False;&lt;br /&gt;with ADOTable1 do&lt;br /&gt;begin&lt;br /&gt;　 {ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;' +&lt;br /&gt;　 'Data Source= D:\;Extended Properties=Text;' +&lt;br /&gt;　 'Persist Security Info=False';&lt;br /&gt;　 TableName := 'AAA#TXT';&lt;br /&gt;　 Open;　 }&lt;br /&gt;　 if Active then&lt;br /&gt; Result := True;&lt;br /&gt;end;&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;function TForm1.Create_QRDBText(Sender: TWinControl; ALeft, ATop, AWidth,&lt;br /&gt;AHight: Integer; AFont: TFont; AAlignMent: TAlignment): TQRDBText;&lt;br /&gt;var&lt;br /&gt;AQRDBText : TQRDBText;&lt;br /&gt;begin&lt;br /&gt;AQRDBText := TQRDBText.Create(Nil);&lt;br /&gt;with AQRDBText do&lt;br /&gt;begin&lt;br /&gt;　 Parent := Sender;&lt;br /&gt;　 Left := ALeft;&lt;br /&gt;　 Top := ATop;&lt;br /&gt;　 Width := AWidth;&lt;br /&gt;　 Height := AHight;&lt;br /&gt;　 AlignMent := AAlignMent;&lt;br /&gt;　 Font.Assign(AFont);&lt;br /&gt;end;&lt;br /&gt;Result := AQRDBText;&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;function TForm1.Create_VLine(Sender: TWinControl; ALeft, ATop, AWidth,&lt;br /&gt;AHight: Integer): TQRShape;&lt;br /&gt;var&lt;br /&gt;AQRShapeV : TQRShape;&lt;br /&gt;begin&lt;br /&gt;AQRShapeV := TQRShape.Create(Nil);&lt;br /&gt;with AQRShapeV do&lt;br /&gt;begin&lt;br /&gt;　 Parent := Sender;&lt;br /&gt;　 Left := ALeft;&lt;br /&gt;　 Top := ATop;&lt;br /&gt;　 Width := AWidth;&lt;br /&gt;　 Height := AHight;&lt;br /&gt;end;&lt;br /&gt;Result := AQRShapeV;&lt;br /&gt;end;&lt;/p&gt;&lt;p&gt;procedure TForm1.Create_Title(Sender: TWinControl; ALeft, ATop, AWidth,&lt;br /&gt;AHight: Integer; ACaption: String; AAlignMent: TAlignment);&lt;br /&gt;var&lt;br /&gt;AQRLabel : TQRLabel;&lt;br /&gt;begin&lt;br /&gt;AQRLabel := TQRLabel.Create(Nil);&lt;br /&gt;with AQRLabel do&lt;br /&gt;begin&lt;br /&gt;　 Parent := Sender;&lt;br /&gt;　 Left := ALeft;&lt;br /&gt;　 Top := ATop;&lt;br /&gt;　 Width := AWidth;&lt;br /&gt;　 AlignMent := AAlignMent;&lt;br /&gt;　 Caption := ACaption;&lt;br /&gt;end;&lt;br /&gt;end;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jiangyuxuan/aggbug/2382838.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/07/2382838.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jiangyuxuan/archive/2012/03/04/2379471.html</id><title type="text">delphi 数据导出 进度条自己生成</title><summary type="text">unit U_func;interfaceuses forms,SysUtils,ComCtrls,DBGrids,DB,Dialogs,Messages,Windows,ComObj,Controls,ADODB,StdCtrls,Graphics;function ProgressBarform(max:integer):tProgressBar;function ExportToExcel(dbgrid:tdbgrid):boolean;function queryExportToExcel(queryexport:tadoquery):boolean;implementation//生</summary><published>2012-03-04T10:49:00Z</published><updated>2012-03-04T10:49:00Z</updated><author><name>江宇旋</name><uri>http://www.cnblogs.com/jiangyuxuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/04/2379471.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/04/2379471.html"/><content type="html">&lt;p&gt;unit U_func;&lt;/p&gt;&lt;p&gt;interface&lt;br /&gt;&amp;nbsp;uses forms,SysUtils,ComCtrls,DBGrids,DB,Dialogs,Messages,Windows,ComObj,Controls,ADODB,StdCtrls,Graphics;&lt;/p&gt;&lt;p&gt;function&amp;nbsp; ProgressBarform(max:integer):tProgressBar;&lt;br /&gt;function ExportToExcel(dbgrid:tdbgrid):boolean;&lt;br /&gt;function queryExportToExcel(queryexport:tadoquery):boolean;&lt;/p&gt;&lt;p&gt;implementation&lt;/p&gt;&lt;p&gt;//生成一个显示进度条的窗体&lt;br /&gt;function&amp;nbsp; ProgressBarform(max:integer):tProgressBar;&lt;br /&gt;&amp;nbsp;&amp;nbsp; var&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1:TProgressBar;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; form:tform;&lt;br /&gt;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; application.CreateForm(tform,form);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; form.Position:=poScreenCenter;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; form.BorderStyle:=bsnone;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; form.Height:=30;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; form.Width:=260;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1:=TProgressBar.Create(form);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.Visible:=true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.Smooth:=true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.Max:=max;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.ParentWindow:=form.Handle;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.Height:=20;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.Width:=250;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.Left:=form.Left+5;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.Top:=form.Top+5;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.Step:=1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; form.show;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result:=ProgressBar1;&lt;br /&gt;&amp;nbsp;&amp;nbsp; end;&lt;/p&gt;&lt;p&gt;//将DBGRID中的内容导入到EXCEL中&lt;br /&gt;function ExportToExcel(dbgrid:tdbgrid):boolean;&lt;br /&gt;&amp;nbsp;&amp;nbsp; const&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xlNormal=-4143;&lt;br /&gt;&amp;nbsp;&amp;nbsp; var&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i,j,k:integer;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; str,filename:string;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; excel:OleVariant;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SavePlace:&amp;nbsp;&amp;nbsp;&amp;nbsp; TBookmark;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog:tsavedialog;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1:TProgressBar;&lt;br /&gt;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result:=false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filename:='';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp; dbgrid.DataSource.DataSet.RecordCount&amp;gt;65536&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if application.messagebox('需要导出的数据过大，Excel最大只能容纳65536行,是否还要继续？','询问',mb_yesno+mb_iconquestion)=idno&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.Cursor:=crHourGlass;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; excel:=CreateOleObject('Excel.Application');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; excel.workbooks.add;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; showmessage('无法调用Excel！');&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog:=tsavedialog.Create(nil);&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog.Filter:='Excel文件(*.xls)|*.xls';&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog.Execute&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; FileExists(savedialog.FileName)&amp;nbsp;&amp;nbsp;&amp;nbsp; then&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; application.messagebox('该文件已经存在，要覆盖吗？','询问',mb_yesno+mb_iconquestion)=idyes&amp;nbsp;&amp;nbsp;&amp;nbsp; then&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DeleteFile(PChar(savedialog.FileName))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Quit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog.free;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Quit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog.free;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filename:=savedialog.FileName;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog.free;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; application.ProcessMessages;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; filename=''&amp;nbsp;&amp;nbsp;&amp;nbsp; then&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result:=false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Quit;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; k:=0;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for&amp;nbsp;&amp;nbsp;&amp;nbsp; i:=0&amp;nbsp;&amp;nbsp;&amp;nbsp; to&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.Columns.count-1&amp;nbsp;&amp;nbsp;&amp;nbsp; do&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.Columns.Items[i].Visible&amp;nbsp;&amp;nbsp;&amp;nbsp; then&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Excel.Columns[k+1].ColumnWidth:=dbgrid.Columns.Items[i].Title.Column.Width;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; excel.cells[1,k+1]:=dbgrid.Columns.Items[i].Title.Caption;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc(k);&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.DataSource.DataSet.DisableControls;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; saveplace:=dbgrid.DataSource.DataSet.GetBookmark;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.DataSource.dataset.First;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i:=2;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.DataSource.DataSet.recordcount&amp;gt;65536&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1:=ProgressBarform(65536)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1:=ProgressBarform(dbgrid.DataSource.DataSet.recordcount);&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while&amp;nbsp;&amp;nbsp;&amp;nbsp; not&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.DataSource.dataset.Eof&amp;nbsp;&amp;nbsp;&amp;nbsp; do&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; k:=0;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for&amp;nbsp;&amp;nbsp;&amp;nbsp; j:=0&amp;nbsp;&amp;nbsp;&amp;nbsp; to&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.Columns.count-1&amp;nbsp;&amp;nbsp;&amp;nbsp; do&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.Columns.Items[j].Visible&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; excel.cells[i,k+1].NumberFormat:='@';&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; not&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.DataSource.dataset.fieldbyname(dbgrid.Columns.Items[j].FieldName).isnull&amp;nbsp;&amp;nbsp;&amp;nbsp; then&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; str := dbgrid.DataSource.dataset.fieldbyname(dbgrid.Columns.Items[j].FieldName).value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Cells[i, k + 1] := Str;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc(k);&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; continue;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; i=65536&amp;nbsp;&amp;nbsp;&amp;nbsp; then&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc(i);&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.StepBy(1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.DataSource.dataset.next;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; progressbar1.Owner.Free;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; application.ProcessMessages;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.DataSource.dataset.GotoBookmark(SavePlace);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dbgrid.DataSource.dataset.EnableControls;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; copy(FileName,length(FileName)-3,4)&amp;lt;&amp;gt;'.xls'&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileName:=FileName+'.xls';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.ActiveWorkbook.SaveAs(FileName,xlNormal,'', '',False,False);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Quit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Excel.Visible&amp;nbsp;&amp;nbsp;&amp;nbsp; :=&amp;nbsp;&amp;nbsp;&amp;nbsp; true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Quit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= true;&lt;br /&gt;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;//将ADOQUERY的数据集导入到EXCEL中&lt;br /&gt;function queryExportToExcel(queryexport:tadoquery):boolean;&lt;br /&gt;&amp;nbsp;&amp;nbsp; const&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xlNormal=-4143;&lt;br /&gt;&amp;nbsp;&amp;nbsp; var&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i,j,k:integer;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; str,filename:string;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; excel:OleVariant;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog:tsavedialog;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1:TProgressBar;&lt;br /&gt;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result:=false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filename:='';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp; queryexport.RecordCount&amp;gt;65536&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; application.messagebox('需要导出的数据过大，Excel最大只能容纳65536行,是否还要继续？','询问',mb_yesno+mb_iconquestion)=idno&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.Cursor:=crHourGlass;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; excel:=CreateOleObject('Excel.Application');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; excel.workbooks.add;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; except&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; showmessage('无法调用Excel！');&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog:=tsavedialog.Create(nil);&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog.Filter:='Excel文件(*.xls)|*.xls';&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog.Execute&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; FileExists(savedialog.FileName)&amp;nbsp;&amp;nbsp;&amp;nbsp; then&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; application.messagebox('该文件已经存在，要覆盖吗？','询问',mb_yesno+mb_iconquestion)=idyes&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DeleteFile(PChar(savedialog.FileName))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Quit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog.free;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Quit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog.free;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filename:=savedialog.FileName;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savedialog.free;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; application.ProcessMessages;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if filename='' then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result:=false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Quit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; k:=0;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for i:=0 to queryexport.FieldCount-1&amp;nbsp;&amp;nbsp;&amp;nbsp; do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; excel.cells[1,k+1]:=queryexport.Fields[i].FieldName;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc(k);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; queryexport.First;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i:=2;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;&amp;nbsp;&amp;nbsp; queryexport.recordcount&amp;gt;65536&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1:=ProgressBarform(65536)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1:=ProgressBarform(queryexport.recordcount);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while&amp;nbsp;&amp;nbsp;&amp;nbsp; not&amp;nbsp;&amp;nbsp;&amp;nbsp; queryexport.Eof&amp;nbsp;&amp;nbsp;&amp;nbsp; do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; k:=0;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for j:=0 to queryexport.FieldCount-1&amp;nbsp;&amp;nbsp;&amp;nbsp; do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; excel.cells[i,k+1].NumberFormat:='@';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not queryexport.fieldbyname(queryexport.Fields[j].FieldName).isnull&amp;nbsp;&amp;nbsp;&amp;nbsp; then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; str:=queryexport.fieldbyname(queryexport.Fields[j].FieldName).AsString;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Cells[i,&amp;nbsp;&amp;nbsp;&amp;nbsp; k&amp;nbsp;&amp;nbsp;&amp;nbsp; +&amp;nbsp;&amp;nbsp;&amp;nbsp; 1]&amp;nbsp;&amp;nbsp;&amp;nbsp; :=&amp;nbsp;&amp;nbsp;&amp;nbsp; Str;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc(k);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if i=65536 then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc(i);&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgressBar1.StepBy(1);&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; queryexport.next;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; progressbar1.Owner.Free;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; application.ProcessMessages;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if copy(FileName,length(FileName)-3,4)&amp;lt;&amp;gt;'.xls' then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileName:=FileName+'.xls';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.ActiveWorkbook.SaveAs(FileName,xlNormal,'', '',False,False);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; except&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Quit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Excel.Visible&amp;nbsp;&amp;nbsp;&amp;nbsp; :=&amp;nbsp;&amp;nbsp;&amp;nbsp; true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Excel.Quit;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; screen.cursor:=crDefault;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result :=&amp;nbsp; true;&lt;br /&gt;&amp;nbsp;&amp;nbsp; end;&lt;/p&gt;&lt;p&gt;end. &lt;/p&gt;&lt;img src="http://www.cnblogs.com/jiangyuxuan/aggbug/2379471.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/04/2379471.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jiangyuxuan/archive/2012/03/04/2379436.html</id><title type="text">delphi执行查询语句时的进度条怎么做</title><summary type="text">procedure TForm1.FormCreate(Sender: TObject); begin ADOQuery1.ExecuteOptions := [eoAsyncFetch];//设为异步读取 end; //ADOQuery的OnFetchProgress事件 procedure TForm1.ADOQuery1FetchProgress(DataSet: TCustomADODataSet; Progress, MaxProgress: Integer; var EventStatus: TEventStatus); begin ProgressBar1.Position ..</summary><published>2012-03-04T10:01:00Z</published><updated>2012-03-04T10:01:00Z</updated><author><name>江宇旋</name><uri>http://www.cnblogs.com/jiangyuxuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/04/2379436.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/04/2379436.html"/><content type="html">&lt;p&gt;procedure TForm1.FormCreate(Sender: TObject);&amp;nbsp; &lt;br /&gt;begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp; ADOQuery1.ExecuteOptions := [eoAsyncFetch];//设为异步读取&amp;nbsp; &lt;br /&gt;end;&amp;nbsp; &lt;br /&gt;//ADOQuery的OnFetchProgress事件&amp;nbsp; &lt;br /&gt;procedure TForm1.ADOQuery1FetchProgress(DataSet: TCustomADODataSet; Progress, MaxProgress: Integer; var EventStatus: TEventStatus);&amp;nbsp; &lt;br /&gt;begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp; ProgressBar1.Position := Progress;&amp;nbsp; &lt;br /&gt;&amp;nbsp; ProgressBar1.Max := MaxProgress;&amp;nbsp; &lt;br /&gt;end;&amp;nbsp; &lt;br /&gt;//ADOQuery的OnFetchComplete事件&amp;nbsp; &lt;br /&gt;procedure TForm1.ADOQuery1FetchComplete(DataSet: TCustomADODataSet; const Error: Error; var EventStatus: TEventStatus);&amp;nbsp; &lt;br /&gt;begin&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp; ProgressBar1.Position := ProgressBar1.Max;&amp;nbsp; &lt;br /&gt;&amp;nbsp; ShowMessage('OK');&amp;nbsp; &lt;br /&gt;end; &lt;/p&gt;&lt;img src="http://www.cnblogs.com/jiangyuxuan/aggbug/2379436.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jiangyuxuan/archive/2012/03/04/2379436.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jiangyuxuan/archive/2012/02/07/2342090.html</id><title type="text">Delphi中动态链接库(DLL)的建立和使用</title><summary type="text">动态链接库是一个能够被应用程序和其它的DLL调用的过程和函数的集合体,它里面包含的是公共代码或资源。由于 DLL代码使用了内存共享技术,在某些地方windows也给了DLL一些更高的权限,因而DLL中可以实现一些一般程序所不能实现的功能,如实现 windows的HOOK、ISAPI等。同时,DLL还为不同语言间代码共享提供了一条方便的途径。因而DLL在编程时应用较为广泛,本文将介绍如何在 Delphi 中建立和使用DLL。一．DLL 库内存共享机制从使用效果看,DLL和unit 很像,它们都可以被别的工程模块所调用,但二者在内部的实现机制上确存在着差别。如果一个程序模块中用uses语句引用了某</summary><published>2012-02-07T15:44:00Z</published><updated>2012-02-07T15:44:00Z</updated><author><name>江宇旋</name><uri>http://www.cnblogs.com/jiangyuxuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/07/2342090.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/07/2342090.html"/><content type="html">动态链接库是一个能够被应用程序和其它的DLL调用的过程和函数的集合体,它里面包含的是公共代码或资源。由于 DLL代码使用了内存共享技术,在某些地方windows也给了DLL一些更高的权限,因而DLL中可以实现一些一般程序所不能实现的功能,如实现 windows的HOOK、ISAPI等。同时,DLL还为不同语言间代码共享提供了一条方便的途径。因而DLL在编程时应用较为广泛,本文将介绍如何在 Delphi 中建立和使用DLL。&lt;br /&gt;&lt;br /&gt;一．DLL 库内存共享机制&lt;br /&gt;&lt;br /&gt;从使用效果看,DLL和unit 很像,它们都可以被别的工程模块所调用,但二者在内部的实现机制上确存在着差别。如果一个程序模块中用uses语句引用了某个unit,编译程序在编译该模块时,便会连同unit一起编译,并把编译后的可执行代码链接到本程序模块中,这就是一个程序模块能够调用所引用unit中过程和函数的原因。当同一个 unit被多个工程所引用时,则每个工程中都含有该unit的可执行代码,当含有该unit的多个工程同时执行时,unit的可执行代码会随不同工程而多次被调入内存,造成内存资源的浪费。DLL则不同,它即使被某个工程调用,编译后仍是独立的,也就是说编译后,一个DLL库形成一个单独的可执行文件,而不与任何其它的可执行文件连接在一起,因而DLL库并不从属于某个特定的工程,当多个工程调用同一个DLL库时只有第一个工程把DLL库调入内存,其余工程并不重复调入同一个DLL库到内存,而是到同一个共享内存区读取。并且,DLL的执行代码是在程序运行期间动态调入的,而不是如unit在程序运行时就与整个工程一起调入内存。这样便可消除unit带来的相同代码多处占用内存的弊病。 &lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;二 Delphi中DLL库的建立&lt;br /&gt;&lt;br /&gt;在Delphi环境中,编写一个DLL同编写一个一般的应用程序并没有太大的区别。事实上作为DLL主体的DLL函数的编写,除了在内存、资源的管理上有所不同外,并不需要其它特别的手段。&lt;br /&gt;&lt;br /&gt;一般工程文件的格式为:&lt;br /&gt;&lt;br /&gt;program工程标题;　&lt;br /&gt;&lt;br /&gt;uses子句;　&lt;br /&gt;&lt;br /&gt;程序体&lt;br /&gt;&lt;br /&gt;而DLLs工程文件的格式为:&lt;br /&gt;&lt;br /&gt;library 工程标题;　&lt;br /&gt;&lt;br /&gt;uses 子句;　&lt;br /&gt;&lt;br /&gt;exprots 子句;　&lt;br /&gt;&lt;br /&gt;程序体&lt;br /&gt;&lt;br /&gt;它们主要的区别有两点:&lt;br /&gt;&lt;br /&gt;1.一般工程文件的头标用program关键字,而DLL工程文件头标用library 关键字。不同的关键字通知编译器生成不同的可执行文件。用program关键字生成的是.exe文件,而用library关键字生成的是.dll文件;&lt;br /&gt;&lt;br /&gt;2.假如DLL要输出供其它应用程序使用的函数或过程,则必须将这些函数或过程列在exports子句中。而这些函数或过程本身必须用export编译指令进行编译。&lt;br /&gt;&lt;br /&gt;在Delphi主菜单file 中选new...项,在弹出的窗口中双击DLL图标,便会自动给出DLL源模块框架,如下:&lt;br /&gt;&lt;br /&gt;Library project1;&lt;br /&gt;&lt;br /&gt;{...注释...}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;&lt;br /&gt;SysUtils, Classes;&lt;br /&gt;&lt;span class="Ojw739"&gt;&lt;/span&gt;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;end.　&lt;br /&gt;&lt;br /&gt;接下来便可在USES和begin之间加入想在该DLL中实现的过程和函数的定义,并用export和exprots保字把它们引出,以便别的模块引用,在begin和end之间加入初始化代码,初始化代码是用来对DLL变量初始化的。应注意,即便无初始化代码begin与end也不可省略,如下例:&lt;br /&gt;&lt;br /&gt;library minmax;&lt;br /&gt;&lt;br /&gt;function Min(X, Y: Integer): Integer; export;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;if X &amp;lt; Y then Min := X else Min := Y;&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function Max(X, Y: Integer): Integer; export;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;if X &amp;gt; Y then Max := X else Max := Y;&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;exports&lt;br /&gt;&lt;br /&gt;Min index 1,&lt;br /&gt;&lt;br /&gt;Max index 2;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;经编译后,并以minmax.DLL存盘后,一个DLL库文件便形成了。&lt;br /&gt;&lt;br /&gt;三 DLL库的访问&lt;br /&gt;&lt;br /&gt;访问DLL库有两种方式,一种是静态引用,另一种是动态引用。&lt;br /&gt;&lt;br /&gt;用静态引用这种方法装入DLL要做两件事情:为DLL 库创建一个输入单元,以及用USES把输入单元连接到要使用DLL 函数的程序模块中。为DLL库创建的输入单元与普通的单元的区别仅在于:在它的接口处声明的过程、函数,并不在它的实现部分给出真正的实现代码,而是用 external关键字把过程、函数的实现细节委托给外部DLL模块。 &lt;div class="Ojw739"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;external命令的使用语法如下:&lt;br /&gt;&lt;br /&gt;procedure /function 过程/函数名;external DLL模块名;&lt;br /&gt;&lt;br /&gt;下面给出为上面创建的minmax.DLL库写的输入单元源文件testdll .pas,从中可看出输入单元与一般单元的一些差别,代码如下所示:&lt;br /&gt;&lt;br /&gt;unit testdll;&lt;br /&gt;&lt;br /&gt;interfacuses&lt;br /&gt;&lt;br /&gt;function Min (X, Y: Integer): Integer;&lt;br /&gt;&lt;br /&gt;function Max (X, Y: Integer): Integer;　&lt;br /&gt;&lt;br /&gt;implementation　&lt;br /&gt;&lt;br /&gt;function Min; external &amp;#8216;minmax.DLL&amp;#8217;;&lt;br /&gt;&lt;br /&gt;function Max; external &amp;#8216;minmax.DLL&amp;#8217;;&lt;br /&gt;&lt;br /&gt;end.　&lt;br /&gt;&lt;br /&gt;一个应用程序若想调用minmax.DLL中的函数,只须在其uses语句中加入testdll 单元即可。&lt;br /&gt;&lt;br /&gt;动态装入DLL,要用到Windows的三个API函数。Loadlibrary、Freelibrary和GetprocAddress 。loadlibrary函数用来装入DLL库,其调用格式如下:&lt;br /&gt;&lt;br /&gt;function loadlobrary (DLLfileName:Pchar): THandle:&lt;br /&gt;&lt;br /&gt;当不再需要一个DLL库时,应调用FreeLibrary函数将其释放,以空出宝贵的内存资源,其调用格式如下:&lt;br /&gt;&lt;br /&gt;procedure FreeLibrary (Libmodule:THandle)&lt;br /&gt;&lt;br /&gt;Libmodule 为由LoadLibrary调用得到的DLL库句柄。在用loadlobrary 函数装入某个DLL库和调用FreeLibrary释放该DLL库之间的程序段中, 可以使用该DLL库中的过程和函数,具体使用方法是:用GetprocAddress函数把DLL库中函数的地址传递给程序中某个函数变量,再用该变量实现DLL函数的调用。GetprocAddress函数声名如下, &lt;p class="Ojw739"&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;function GetprocAddress (Libmodule:THandle:procname:pchar):TFarProc:　&lt;br /&gt;&lt;br /&gt;如下例所示:&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;&lt;br /&gt;TTimeRec = record&lt;br /&gt;&lt;br /&gt;Second: Integer;&lt;br /&gt;&lt;br /&gt;Minute: Integer;&lt;br /&gt;&lt;br /&gt;Hour: Integer;&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;TGetTime = procedure(var Time: TTimeRec);&lt;br /&gt;&lt;br /&gt;THandle = Integer;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;&lt;br /&gt;Time: TTimeRec;&lt;br /&gt;&lt;br /&gt;Handle: THandle;&lt;br /&gt;&lt;br /&gt;GetTime: TGetTime;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;Handle := LoadLibrary('DATETIME.DLL');&lt;br /&gt;&lt;br /&gt;if Handle &amp;lt;&amp;gt; 0 then&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;@GetTime := GetProcAddress(Handle, 'GetTime');&lt;br /&gt;&lt;br /&gt;if @GetTime &amp;lt;&amp;gt; nil then&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;GetTime(Time);&lt;br /&gt;&lt;br /&gt;with Time do&lt;br /&gt;&lt;br /&gt;WriteLn('The time is ', Hour, ':', Minute, ':', Second);&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;FreeLibrary(Handle);&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;在调用动态链接库时应注意, 所需动态链接库须与应用程序在同一目录或Windows System 目录下。动态链接库是 Windows下程序组织的一种重要方式,使用动态链接库可以极大地保护用户在不同开发工具、不同时期所做的工作,提高编程效率。&lt;br /&gt;&lt;img src="http://www.cnblogs.com/jiangyuxuan/aggbug/2342090.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/07/2342090.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339919.html</id><title type="text">术语表</title><summary type="text">这里列出了本书中用到的一些技术术语，在别的地方你也能找到它们，不过我想还是把它们集中一处，以便查找。 堆(内存)堆表示程序可用的内存区，也叫动态内存区。堆内存的分配与释放次序是随机的，这就是说，如果你按次序分配三块内存，那么到时并不按分配时的次序释放内存。 堆管理器会负责所有操作，你只需简单地使用GetMem 函数请求新内存或调用constructor 建立对象， Delphi 会返回一个新的内存块(随意重用已经丢弃的内存块)。 堆是应用程序可用的三种内存区之一， 其它两种分别是全局内存区(存放全程变量) 和栈。与堆相反，全程变量内存在程序启动时就分配，然后一直保留到程序终止才释放；栈的内容请</summary><published>2012-02-06T04:59:00Z</published><updated>2012-02-06T04:59:00Z</updated><author><name>江宇旋</name><uri>http://www.cnblogs.com/jiangyuxuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339919.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339919.html"/><content type="html">&lt;p class="MsoPlainText"&gt;这里列出了本书中用到的一些技术术语，在别的地方你也能找到它们，不过我想还是把它们集中一处，以便查找。 &lt;p&gt;&lt;strong&gt;堆(内存)&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;堆表示程序可用的内存区，也叫动态内存区。堆内存的分配与释放次序是随机的，这就是说，如果你按次序分配三块内存，那么到时并不按分配时的次序释放内存。 堆管理器会负责所有操作，你只需简单地使用GetMem 函数请求新内存或调用constructor 建立对象， Delphi 会返回一个新的内存块(随意重用已经丢弃的内存块)。 &lt;p class="MsoPlainText"&gt;堆是应用程序可用的三种内存区之一， 其它两种分别是全局内存区(存放全程变量) 和栈。与堆相反，全程变量内存在程序启动时就分配，然后一直保留到程序终止才释放；栈的内容请详见术语表。 &lt;p class="MsoPlainText"&gt;Delphi 使用堆为对象、字符串、动态数组及特殊的动态内存请求(GetMem)内存分配。 &lt;p class="MsoPlainText"&gt;Windows 应用程序的地址空间最大允许有 2 GigaByte, 其中大部分能被堆使用。 &lt;p&gt;&lt;strong&gt;栈(内存)&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;栈表示程序可用的内存区，栈内存动态分配，并按特定次序分配、释放。栈内存按后进先出次序(LIFO)分配，这表示最后分配的内存区先被释放。栈内存一般在例程中使用(过程、函数及方法调用)。 当你调用例程时，例程参数及返回值是放在栈中的(除非使用Delphi缺省调用方式，对调用过程进行优化)。此外，例程中声明的变量(在begin语句前的 &lt;em&gt;var&lt;/em&gt; 块中)也存放在栈中，所以当例程终止时，这些变量会被自动清除(在返回调用点之前以LIFO次序释放)。 &lt;p class="MsoPlainText"&gt;栈是应用程序可用的三种内存区之一，其它两种分别是全局内存区和堆。堆的内容请详见术语表。 &lt;p class="MsoPlainText"&gt;Delphi 使用栈存放例程参数及其返回值(除非你使用Delphi缺省的 register 调用协定)、局部例程变量、Windows API 函数调用等等。 &lt;p class="MsoPlainText"&gt;Windows 应用程序可以预留大量的栈内存，在 Delphi 中你可以通过工程选项的 linker 页设置, 不过一般采用缺省设置就可以了。 如果你收到一个栈溢出错误信息，这可能是因为你的函数进入了死循环自调用，而不是栈空间太小。 &lt;p&gt;&lt;strong&gt;其它&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Dynamic&lt;/li&gt;&lt;li&gt;Static&lt;/li&gt;&lt;li&gt;Virtual&lt;/li&gt;&lt;li&gt;memory leak&lt;/li&gt;&lt;li&gt;painting&lt;/li&gt;&lt;li&gt;literal&lt;/li&gt;&lt;li&gt;array&lt;/li&gt;&lt;li&gt;API&lt;/li&gt;&lt;li&gt;class reference&lt;/li&gt;&lt;li&gt;class method&lt;/li&gt;&lt;li&gt;parent&lt;/li&gt;&lt;li&gt;owner&lt;/li&gt;&lt;li&gt;self &lt;/li&gt;&lt;/ul&gt;&lt;img src="http://www.cnblogs.com/jiangyuxuan/aggbug/2339919.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339919.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339915.html</id><title type="text">Variant类型</title><summary type="text">为了完全支持OLE，32位Delphi 增加了Variant 数据类型，本节将从宏观角度来分析这种数据类型。实际上，Variant类型对Pascal语言有普遍而深入的影响，Delphi 控件库中与OLE 无关的地方也使用到这种类型。Variant变量没有类型 一般说来，你可以用Variant 变量存储任何数据类型，对它执行各种操作和类型转换。需要注意的是：这违反了Pascal 语言的一贯原则，有悖于良好的编程习惯。variant 变量的类型检查和计算在运行期间才进行，编译器不会提示代码中的潜在错误，这些错误在进一步测试中才能发现。总之，你可以认为包含variant变量的代码是解释性代码，正如解</summary><published>2012-02-06T04:58:00Z</published><updated>2012-02-06T04:58:00Z</updated><author><name>江宇旋</name><uri>http://www.cnblogs.com/jiangyuxuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339915.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339915.html"/><content type="html">&lt;p class="MsoPlainText"&gt;为了完全支持&lt;span lang="EN-US"&gt;OLE，32位Delphi 增加了Variant 数据类型，本节将从宏观角度来分析这种数据类型。实际上，Variant类型对Pascal语言有普遍而深入的影响，Delphi 控件库中与OLE 无关的地方也使用到这种类型。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;Variant变量没有类型&lt;/font&gt; &lt;p class="MsoPlainText"&gt;一般说来，你可以用&lt;span lang="EN-US"&gt;Variant 变量存储任何数据类型，对它执行各种操作和类型转换。需要注意的是：这违反了Pascal 语言的一贯原则，有悖于良好的编程习惯。variant 变量的类型检查和计算在运行期间才进行，编译器不会提示代码中的潜在错误，这些错误在进一步测试中才能发现。总之，你可以认为包含variant变量的代码是解释性代码，正如解释性代码一样，许多操作直到执行时才能知道，这对代码运行速度会有很大的影响。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;上面对&lt;span lang="EN-US"&gt;Variant 类型的使用提出了警告，现在来看看Variant 类型究竟能干什么。基本上说，如果声明了一个variant 变量：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;br/&gt;  V: Variant;&lt;p class="MsoPlainText"&gt;你就可以把各种不同类型的值赋给它：&lt;/p&gt;V := 10;&lt;br/&gt;V := &lt;em&gt;'Hello, World'&lt;/em&gt;;&lt;br/&gt;V := 45.55;&lt;p class="MsoPlainText"&gt;一旦得到一个&lt;span lang="EN-US"&gt;variant 值，你可以把它拷贝给任何兼容或不兼容的数据类型。如果你把值赋给不兼容的数据类型，Delphi 会力尽所能进行转换，无法转换则颁布一个运行时间错误。实际上，variant变量中不仅包含了数据还包含有类型信息，并允许一系列运行时间操作,这些操作很方便，但运行速度慢且安全性差。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;见例&lt;span lang="EN-US"&gt;VariTest，它是上面代码的扩展。窗体上有三个编辑框，一对按钮，第一个按钮的OnClick 事件代码如下： &lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure&lt;/strong&gt; TForm1.Button1Click(Sender: TObject);&lt;br/&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;br/&gt;  V: Variant;&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  V := 10;&lt;br/&gt;  Edit1.Text := V;&lt;br/&gt;  V := &lt;em&gt;'Hello, World'&lt;/em&gt;;&lt;br/&gt;  Edit2.Text := V;&lt;br/&gt;  V := 45.55;&lt;br/&gt;  Edit3.Text := V;&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;很有趣是不是？你可以把一个值为字符串的&lt;span lang="EN-US"&gt;variant 变量赋给编辑框Text 属性，还可以把值为整数或浮点数的variant 变量赋给Text属性。正如你在图10.1中所看到的，一切正常。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;（图&lt;span lang="EN-US"&gt;10.1）按Assign按钮后，例VariTest的输出结果&lt;/span&gt;&lt;/p&gt;&lt;p class="slug"&gt;图 10.1: 例 VariTest 的 Assign 按钮 Click 事件输出结果&lt;/p&gt;&lt;p&gt;&lt;img border="0" alt="" src="http://www.cnblogs.com/jiangyuxuan/admin/mk:@MSITStore:F:/TDDOWNLOAD/Pascal%20精要(中文CHM格式）.chm::/epf1001.gif" width="301" height="168" /&gt; &lt;p class="MsoPlainText"&gt;更糟糕的是&lt;span lang="EN-US"&gt;:你还可以用variant变量计算数值，从第二个按钮的Click事件代码就可看到这一点：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure&lt;/strong&gt; TForm1.Button2Click(Sender: TObject);&lt;br/&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;br/&gt;  V: Variant;&lt;br/&gt;  N: Integer;&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  V := Edit1.Text;&lt;br/&gt;  N := Integer(V) * 2;&lt;br/&gt;  V := N;&lt;br/&gt;  Edit1.Text := V;&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;至少这种代码带有一定危险性，如果第一个编辑框包含了一个数字，那么一切运行正常；如果不是，将会引发异常。这里再重申一遍，如果不到万不得以，不要随便使用&lt;span lang="EN-US"&gt;Variant 类型，还是应坚持使用传统的Pascal 数据类型和类型检查方法。在Delphi 和 VCL中，variant变量主要是用于 OLE 支持和数据库域的访问。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;Variant类型内部结构&lt;/font&gt; &lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Delphi中定义了一个 variant 记录类型，&lt;em&gt;TVarData&lt;/em&gt;，它与Variant 类型有相同的内存布局。你可以通过&lt;em&gt;TVarData&lt;/em&gt;访问variant变量的实际类型。&lt;em&gt;TVarData&lt;/em&gt; 结构中包含了Variant类型信息(由Vtype域表示)、一些保留域及当前值。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;VType域的取值包括OLE 自动化中的所有数据类型，这些类型通常叫OLE 类型或variant 类型。以下是variant 类型的完整列表，按字母顺序排列：&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;varArray&lt;/li&gt;&lt;li&gt;varBoolean&lt;/li&gt;&lt;li&gt;varByRef&lt;/li&gt;&lt;li&gt;varCurrency&lt;/li&gt;&lt;li&gt;varDate&lt;/li&gt;&lt;li&gt;varDispatch&lt;/li&gt;&lt;li&gt;varDouble&lt;/li&gt;&lt;li&gt;varEmpty&lt;/li&gt;&lt;li&gt;varError&lt;/li&gt;&lt;li&gt;varInteger&lt;/li&gt;&lt;li&gt;varNull&lt;/li&gt;&lt;li&gt;varOleStr&lt;/li&gt;&lt;li&gt;varSingle&lt;/li&gt;&lt;li&gt;varSmallint&lt;/li&gt;&lt;li&gt;varString&lt;/li&gt;&lt;li&gt;varTypeMask&lt;/li&gt;&lt;li&gt;varUnknown&lt;/li&gt;&lt;li&gt;varVariant &lt;/li&gt;&lt;/ul&gt;&lt;p class="MsoPlainText"&gt;你可以在&lt;span lang="EN-US"&gt;Delphi 帮助系统的variants 主题下找到这些类型的说明。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;还有许多操作&lt;span lang="EN-US"&gt;variant 变量的函数，你可以用它们进行特定的类型转换，或通过它们获取variant变量的类型信息（例如VarType 函数），当你用variant变量写表达式时，Delphi会自动调用这些类型转换和赋值函数。另外还有操作variant 数组的例程，你可以通过帮助文件的Variant support routines 主题了解相关内容。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;Variant类型运行很慢！&lt;/font&gt; &lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Variant 类型代码运行很慢，不仅数据类型转换如此，两个值为整数的Variant 变量相加也是如此。它们几乎跟Visual Basic这种解释性代码一样慢！为了比较Variant变量和整型变量的运行速度，请看例VSpeed 。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;程序中设置了一个循环，记录运行时间并在进程条中显示运行状态。下面是基于&lt;span lang="EN-US"&gt;variant类型的一段代码，基于整型的代码与此相似：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure&lt;/strong&gt; TForm1.Button1Click(Sender: TObject);&lt;br/&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;br/&gt;  time1, time2: TDateTime;&lt;br/&gt;  n1, n2: Variant;&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  time1 := Now;&lt;br/&gt;  n1 := 0;&lt;br/&gt;  n2 := 0;&lt;br/&gt;  ProgressBar1.Position := 0;&lt;br/&gt;  &lt;strong&gt;while&lt;/strong&gt; n1 &amp;lt; 5000000 &lt;strong&gt;do&lt;/strong&gt;&lt;br/&gt;  &lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;    n2 := n2 + n1;&lt;br/&gt;    Inc (n1);&lt;br/&gt;    &lt;strong&gt;if&lt;/strong&gt; (n1 &lt;strong&gt;mod&lt;/strong&gt; 50000) = 0 &lt;strong&gt;then&lt;/strong&gt;&lt;br/&gt;    &lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;      ProgressBar1.Position := n1 &lt;strong&gt;div&lt;/strong&gt; 50000;&lt;br/&gt;      Application.ProcessMessages;&lt;br/&gt;    &lt;strong&gt;end&lt;/strong&gt;;&lt;br/&gt;  &lt;strong&gt;end&lt;/strong&gt;;&lt;br/&gt;  &lt;em&gt;// we must use the result&lt;/em&gt;&lt;br/&gt;  Total := n2;&lt;br/&gt;  time2 := Now;&lt;br/&gt;  Label1.Caption := FormatDateTime (&lt;br/&gt;    &lt;em&gt;'n:ss'&lt;/em&gt;, Time2-Time1) + &lt;em&gt;' seconds'&lt;/em&gt;;&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;记时这段代码值得一看，因为你可以把它用到任何类型的性能测试中。正如你所看到的，程序用&lt;span lang="EN-US"&gt;Now 函数获取当前的时间，用FormatDateTime 函数格式化时间差，输出结果以分("n")和秒("ss")表示。除此之外，你可以用Windows API的GetTickCount 函数，该函数能精确显示操作系统启动后至当前的毫秒数。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;从上例可见两者的速度差异非常之大，以至于不用精确记时也能看到这种差异。图&lt;span lang="EN-US"&gt;10.2是在本人计算机上运行程序看到的结果。当然运行结果取决于运行程序的计算机，但是两者的数值比不会有太大变化。&lt;/span&gt;&lt;/p&gt;&lt;p class="slug"&gt;图 10.2: 例Vspeed中整型与Variant类型的计算速度差异&lt;/p&gt;&lt;p&gt;&lt;img border="0" alt="" src="http://www.cnblogs.com/jiangyuxuan/admin/mk:@MSITStore:F:/TDDOWNLOAD/Pascal%20精要(中文CHM格式）.chm::/epf1002.gif" width="319" height="167" /&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;结束语&lt;/font&gt; &lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Variant类型与传统Pascal 数据类型差别很大，所以本章以短小篇幅单独阐述了Variant类型的有关内容。尽管Variant类型主要用于OLE 编程，但用来写一些潦潦草草的程序倒也便利，因为不用考虑数据类型，不过正如以上所述，这样做会影响程序执行速度。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;通过前面各章我们已经介绍了绝大部分的语言特征，下一章将讨论程序的总体框架和单元模块。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jiangyuxuan/aggbug/2339915.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339915.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339917.html</id><title type="text">程序和单元</title><summary type="text">Delphi 应用程序中的单元，或说程序模块可谓老道精深。实际上，单元是程序模块化的基础，类是继它之后才有的。在Delphi 应用程序中，每个窗体都有一个相对应的单元。用相应的工具按钮, 或File &gt; New Form 菜单命令，在工程中添加一个新窗体，实际上是增加了一个新单元，也就是建立了该新窗体的类。单元 虽然所有窗体都在单元中定义，但反之则不然。除窗体外，单元中还可以定义一系列能访问的例程。选择File &gt; New菜单命令，然后在Object Repository的New 页中选择Unit 图标，随即当前工程中就会加入一个空白单元。单元代码分区存放，空白单元的代码如下：un</summary><published>2012-02-06T04:58:00Z</published><updated>2012-02-06T04:58:00Z</updated><author><name>江宇旋</name><uri>http://www.cnblogs.com/jiangyuxuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339917.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339917.html"/><content type="html">&lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Delphi 应用程序中的单元，或说程序模块可谓老道精深。实际上，单元是程序模块化的基础，类是继它之后才有的。在Delphi 应用程序中，每个窗体都有一个相对应的单元。用相应的工具按钮, 或File &amp;gt; New Form 菜单命令，在工程中添加一个新窗体，实际上是增加了一个新单元，也就是建立了该新窗体的类。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;单元&lt;/font&gt; &lt;p class="MsoPlainText"&gt;虽然所有窗体都在单元中定义，但反之则不然。除窗体外，单元中还可以定义一系列能访问的例程。选择&lt;span lang="EN-US"&gt;File &amp;gt; New菜单命令，然后在Object Repository的New 页中选择Unit 图标，随即当前工程中就会加入一个空白单元。单元代码分区存放，空白单元的代码如下：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;unit&lt;/strong&gt; Unit1;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;interface&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;implementation&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;.&lt;p class="MsoPlainText"&gt;单元的概念比较简单，单元名与文件名相同，而且必须唯一。单元包括界面区（&lt;span lang="EN-US"&gt;interface）及实现区(implementation)，界面区用于声明其它单元能看到的部分；实现区存放界面的实现代码及外部不可见的声明。此外还有两个可选的区，即初始化区及结束区，其中初始化区存放初始化代码，当程序加载到内存时执行；结束区存放程序终止时执行的代码。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;单元总体结构如下：&lt;/p&gt;&lt;strong&gt;unit&lt;/strong&gt; unitName;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;interface&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;// other units we need to refer to&lt;/em&gt;&lt;br/&gt;&lt;strong&gt;uses&lt;/strong&gt;&lt;br/&gt;  A, B, C;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;// exported type definition&lt;/em&gt;&lt;br/&gt;&lt;strong&gt;type&lt;/strong&gt;&lt;br/&gt;  newType = TypeDefinition;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;// exported constants&lt;/em&gt;&lt;br/&gt;&lt;strong&gt;const&lt;/strong&gt;&lt;br/&gt;  Zero = 0;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;// global variables&lt;/em&gt;&lt;br/&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;br/&gt;  Total: Integer;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;// list of exported functions and procedures&lt;/em&gt;&lt;br/&gt;&lt;strong&gt;procedure&lt;/strong&gt; MyProc;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;implementation&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;uses&lt;/strong&gt;&lt;br/&gt;  D, E;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;// hidden global variable&lt;/em&gt;&lt;br/&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;br/&gt;  PartialTotal: Integer;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;// all the exported functions must be coded&lt;/em&gt;&lt;br/&gt;&lt;strong&gt;procedure&lt;/strong&gt; MyProc;&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  &lt;em&gt;// ... code of procedure MyProc&lt;/em&gt;&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;initialization&lt;/strong&gt;&lt;br/&gt;  &lt;em&gt;// optional initialization part&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;finalization&lt;/strong&gt;&lt;br/&gt;  &lt;em&gt;// optional clean-up code&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;.&lt;p class="MsoPlainText"&gt;界面区头部的&lt;span lang="EN-US"&gt;uses子句表示需要访问的外部单元，这些外部单元中定义了你需要引用的数据类型，如自定义窗体内所用的控件。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;实现区头部的&lt;span lang="EN-US"&gt;uses子句用于表示只在实现部分访问的单元。如果例程或方法的代码需要引用其他单元，你应该把这些单元加到实现区子句中，而不是界面区。你所引用的单元必须在工程文件目录中能找到，或在工程选项对话框的 Directories/Conditionals 页设定这些单元的搜索路径。&lt;/span&gt;&lt;/p&gt;&lt;p class="note"&gt;C++程序员应该知道uses语句和include 指令是不同的。uses语句只是用于输入引用单元的预编译界面部分，引用单元的实现部分在单元编译时才考虑。你引用的单元可以是源代码格式（PAS），也可以是编译格式（DCU），但是必须用同一版本的Delphi进行编译。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;在单元的界面区中可以声明许多不同的元素，包括过程、函数、全程变量及数据类型。在&lt;span lang="EN-US"&gt;Delphi 应用程序中，数据类型可能用得最频繁。每创建一个窗体，Delphi 会在单元中自动建立一个新的数据类型--类(class)。在Delphi 单元中不仅能定义窗体；还能象传统单元一样，只包含过程及函数；还可以定义与窗体和任何可视控件无关的类。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;单元的工作空间&lt;/font&gt; &lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Pascal单元是封装性和可视性的关键，它很可能比类中的 private 和 public 关键字还要重要。(实际上，private关键字与类单元的工作空间有关)。一个标识符（如一个变量、过程、函数或数据类型）的工作空间是指能访问标识符的代码段。基本原则是:标识符在它工作空间内才有意义，也就是说，只在其声明的代码块中才有意义，在工作空间外你不能访问这些标识符。例如：&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;局部变量：如果你在例程或方法代码块内声明一个变量，那么单元外部不能访问这个变量。该标识符的工作空间就是定义标识符的整个例程，其中包括嵌套例程（除非嵌套例程内有一个同名标识符覆盖了外部定义）。当调用到例程时，其变量压入栈内存中，例程一结束，栈中的内存就自动释放。 &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;全程隐藏变量：如果你在单元的实现部分声明一个标识符，那么在单元外你不能使用它，但是能在单元内任一代码块及过程中使用它。程序一启动就会为全程隐藏变量分配内存，程序终止内存释放，你可以在单元初始化区给它赋初值。 &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;全程变量：如果你在单元的界面部分声明标识符，那么该标识符的工作空间就扩大了，任何Use它的单元都能访问它。这类变量的内存分配及生命周期与上类变量相同，唯一不同的是其可见性。 &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class="MsoPlainText"&gt;只要程序单元的&lt;span lang="EN-US"&gt;uses子句中列出某一单元名，那么所列单元界面区中声明的任何标识符该程序都能访问。窗体类的变量就是这样声明的，所以你可以在其他窗体代码中访问这个窗体以及它的公共域、方法、属性和组件。当然把什么都声明为全局标识这种编程习惯并不好。除了明显的内存消耗问题外，使用全程变量使代码维护和更新变得困难。一句话，你应该尽量少用全程变量。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;单元用作命名空间&lt;/font&gt; &lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;uses 语句是访问其他单元工作空间的标准技术，通过该语句你能访问其它单元的定义内容。如果恰巧两个单元声明的标识符同名，也就是说你可能有两个同名的类或例程，遇到这种情况，你可以用单元名作前缀定义类型或过程名，由此进行区分。例如用Totals.ComputeTotal访问Totals 单元中的ComputeTotal 过程。不过这种情况最好不要经常遇到，因此强烈建议不要在同一程序中用同一名字表示两个不同的东西。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;然而，如果查阅&lt;span lang="EN-US"&gt;VCL库和Windows 文件，你会发现一些Delphi 函数和Delphi 可用的Windows API 函数同名，不过参数往往不同，下面以Beep 过程为例说明这个问题。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;新建一个&lt;span lang="EN-US"&gt;Delphi 程序，添加一个按钮，然后写入以下代码：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure&lt;/strong&gt; TForm1.Button1Click(Sender: TObject);&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  Beep;&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;执行程序，单击按钮，你会听到一个短促的声音。现在移到单元的&lt;span lang="EN-US"&gt;uses语句，把原先的代码：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;uses&lt;/strong&gt;&lt;br/&gt;  Windows, Messages, SysUtils, Classes, ...&lt;p class="MsoPlainText"&gt;改为下面的样式，只要把&lt;em&gt;&lt;span lang="EN-US"&gt;SysUtils&lt;/span&gt;&lt;/em&gt;单元移到&lt;em&gt;&lt;span lang="EN-US"&gt;Windows&lt;/span&gt;&lt;/em&gt;之前：&lt;/p&gt;&lt;strong&gt;uses&lt;/strong&gt;&lt;br/&gt;  SysUtils, Windows, Messages, Classes, ...&lt;p class="MsoPlainText"&gt;现在如果重新编译这段代码，你会得到一个编译错误：&lt;span style="font-family: 'Courier New'; mso-ascii-font-family: 宋体; mso-bidi-font-family: 'Times New Roman'" lang="EN-US"&gt;&amp;#8221;&lt;/span&gt;&lt;span lang="EN-US"&gt;Not enough actual parameters&lt;/span&gt;&lt;span style="font-family: 'Courier New'; mso-ascii-font-family: 宋体; mso-bidi-font-family: 'Times New Roman'" lang="EN-US"&gt;&amp;#8221;&lt;/span&gt;（实际参数不够）。问题在于&lt;span lang="EN-US"&gt;Windows 单元定义了另一个带两个参数的Beep 函数。应该说uses子句中第一个单元的定义被后面单元的定义覆盖，解决方法很简单：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure&lt;/strong&gt; TForm1.Button1Click(Sender: TObject);&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  SysUtils.Beep;&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;不管&lt;span lang="EN-US"&gt;uses子句中单元顺序如何排列，以上代码都能编译通过。在Delphi中很少有其他命名冲突的情况，因为Delphi 代码通常放在类的方法中，如果不同类中有两个同名的方法不会产生任何冲突，只是使用全程例程会产生冲突问题。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;单元和程序&lt;/font&gt; &lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Delphi 应用程序源代码文件可分成两类，它们是一个或多个单元文件及一个程序文件，单元文件可以看成是次一级的文件，它被应用程序的主体&amp;#8212;&amp;#8212;程序文件&amp;#8212;&amp;#8212;引用。理论上如此，实际上程序文件通常是自动产生的，作用有限，程序启动并运行主窗体时才会用到它。程序文件的代码，或说Delphi 工程文件（DPR），可用手工进行编辑，也可通过工程管理器及其与应用程序、窗体相关的选项进行编辑。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;程序文件的结构通常比单元文件的结构简单得多。下面是一个程序文件的源代码：&lt;/p&gt;&lt;strong&gt;program&lt;/strong&gt; Project1;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;uses&lt;/strong&gt;&lt;br/&gt;  Forms,&lt;br/&gt;  Unit1 &lt;strong&gt;in&lt;/strong&gt; &lt;em&gt;Unit1.PAS� {Form1DateForm}&lt;/em&gt;;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  Application.Initialize;&lt;br/&gt;  Application.CreateForm (TForm1, Form1);&lt;br/&gt;  Application.Run;&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;.&lt;p class="MsoPlainText"&gt;从上可见，文件中只有一个&lt;span lang="EN-US"&gt;uses区和应用程序的主体代码，主体代码包含在begin 和 end 关键字之间。程序的uses子句特别重要，因为需要通过它来管理应用程序的编译和连接。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;结束语&lt;/font&gt; &lt;p class="MsoPlainText"&gt;讨论完&lt;span lang="EN-US"&gt;Delphi中Pascal 应用程序的结构，本书就翻过了最后一章，至少目前是这样，欢迎来email发表你的意见和要求。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;如果想进一步学习&lt;/span&gt;&lt;span lang="EN-US"&gt;Delphi Object Pascal&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;中面向对象的内容，你可以参考我已出版的书《精通&lt;/span&gt;&lt;span lang="EN-US"&gt;Delphi 5&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;》（&lt;/span&gt;&lt;strong&gt;&lt;em&gt;&lt;span lang="EN-US"&gt;Mastering Delphi 5&lt;/span&gt;&lt;/em&gt;&lt;/strong&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;Sybex,1999&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;），详细情况可访问网址&lt;/span&gt;&lt;strong&gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.marcocanto.com/"&gt;http://www.marcocanto.com/&lt;/a&gt;&lt;/span&gt;&lt;/strong&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;，你也可以从该网址上下载本书的最新版本。&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jiangyuxuan/aggbug/2339917.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339917.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339914.html</id><title type="text">Windows 编程</title><summary type="text">Delphi 利用Object Pascal 和可视控件库（VCL）对底层的Windows API 进行了完美的封装，所以很少需要使用基础Pascal 语言来建立Windows应用程序，也无需直接调用Windows API 函数。尽管如此，如果遇到特殊情况，VCL 又不支持，Delphi程序员还得直接面对Windows编程。不过只有在极其特殊的情况下，例如：基于不寻常API 调用的Delphi新控件开发， 你才需要这样做，这里我不想讨论这方面内容，我只想让大家看一下与操作系统交互的几个Delphi元素以及Delphi程序员能从中获益的Windows编程技术。Windows 句柄 Delphi从</summary><published>2012-02-06T04:57:00Z</published><updated>2012-02-06T04:57:00Z</updated><author><name>江宇旋</name><uri>http://www.cnblogs.com/jiangyuxuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339914.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339914.html"/><content type="html">&lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Delphi 利用Object Pascal 和可视控件库（VCL）对底层的Windows API 进行了完美的封装，所以很少需要使用基础Pascal 语言来建立Windows应用程序，也无需直接调用Windows API 函数。尽管如此，如果遇到特殊情况，VCL 又不支持，Delphi程序员还得直接面对Windows编程。不过只有在极其特殊的情况下，例如：基于不寻常API 调用的Delphi新控件开发， 你才需要这样做，这里我不想讨论这方面内容，我只想让大家看一下与操作系统交互的几个Delphi元素以及Delphi程序员能从中获益的Windows编程技术。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;Windows 句柄&lt;/font&gt; &lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Delphi从Windows 引入了不少数据类型，其中句柄最重要。这种数据类型名为THandle，该类型在Windows 单元中定义：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;type&lt;/strong&gt;&lt;br/&gt;  THandle = LongWord;&lt;br/&gt;&lt;p class="MsoPlainText"&gt;句柄数据类型通过数字实现，但并不当数字用。在&lt;span lang="EN-US"&gt;Windows 中，句柄是一个系统内部数据结构的引用。例如，当你操作一个窗口，或说是一个Delphi 窗体时，系统会给你一个该窗口的句柄，系统会通知你：你正在操作142号窗口，就此，你的应用程序就能要求系统对142号窗口进行操作&amp;#8212;&amp;#8212;移动窗口、改变窗口大小、把窗口极小化为图标，等等。实际上许多Windows API 函数把句柄作为它的第一个参数，如GDI （图形设备接口）句柄、菜单句柄、实例句柄、位图句柄等等，不仅仅局限于窗口函数，。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;换句话说，句柄是一种内部代码，通过它能引用受系统控制的特殊元素，如窗口、位图、图标、内存块、光标、字体、菜单等等。&lt;span lang="EN-US"&gt;Delphi中很少需要直接使用句柄，因为句柄藏在窗体、位图及其他Delphi对象的内部。当你要调用Delphi不支持的Windows API 函数时，句柄才会有用。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;现在举一个简单的&lt;span lang="EN-US"&gt;Windows句柄例子，完善这节内容。例WHandle 程序的窗体很简单，只有一个按钮。正如下面主窗体文本所定义的那样，我在代码中添加了窗体的OnCreate 事件和按钮的OnClick 事件：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;object&lt;/strong&gt; FormWHandle: TFormWHandle&lt;br/&gt;  Caption = &lt;em&gt;'Window Handle'&lt;/em&gt;&lt;br/&gt;  OnCreate = FormCreate&lt;br/&gt;  &lt;strong&gt;object &lt;/strong&gt;BtnCallAPI: TButton&lt;br/&gt;    Caption = &lt;em&gt;'Call API'&lt;/em&gt;&lt;br/&gt;    OnClick = BtnCallAPIClick&lt;br/&gt;&lt;strong&gt;  end&lt;br/&gt;end&lt;/strong&gt;&lt;p class="MsoPlainText"&gt;窗体一创建，程序就会通过窗体本身的&lt;span lang="EN-US"&gt;Handle 属性，获取窗体对应的窗口句柄。调用IntToStr ，把句柄数值转换为一个字符串，然后再把它添加到窗体标题中，如图9.1：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure&lt;/strong&gt; TFormWHandle.FormCreate(Sender: TObject);&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  Caption := Caption + &lt;em&gt;' '&lt;/em&gt; + IntToStr (Handle);&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;因为&lt;span lang="EN-US"&gt;FormCreate 是窗体类的方法，它可直接访问同类的其他属性和方法。因此，在这个过程中我们能够直接访问窗体的Caption 属性和Handle 属性。&lt;/span&gt;&lt;/p&gt;&lt;p class="slug"&gt;图 9.1: 例 WHandle 显示窗体句柄，每次运行程序得到的句柄值不同 &lt;p&gt;&lt;img border="0" alt="" src="http://www.cnblogs.com/jiangyuxuan/admin/mk:@MSITStore:F:/TDDOWNLOAD/Pascal%20精要(中文CHM格式）.chm::/epf0901.gif" width="259" height="115" /&gt; &lt;p class="MsoPlainText"&gt;如果你多此次执行该程序，通常会获得不同的句柄值。这个值实际上是由&lt;span lang="EN-US"&gt;Windows 操作系统确定并返回给应用程序的。（句柄从来不是由程序决定的，而且句柄没有预定义值，句柄是由系统决定的，每执行一次程序，产生一个新值。）&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;当你单击按钮，程序将调用&lt;span lang="EN-US"&gt;Windows API 函数SetWindowText，它会根据第一个传递参数改变窗口的标题。更准确地说，所用的API 函数其第一个参数是需要修改窗体的句柄：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure &lt;/strong&gt;TFormWHandle.BtnCallAPIClick(Sender: TObject);&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  SetWindowText (Handle, &lt;em&gt;'Hi'&lt;/em&gt;);&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;这段代码与前面所讲的事件处理程序等效，它通过给窗体的&lt;span lang="EN-US"&gt;Caption 属性赋一个新值，改变窗体的标题。对上面这种情况，调用一个API 函数没有什么意义，因为用Delphi来做更简单。然而有些API在Delphi中没有相应的函数，就需要直接调用API，这一点你会在后面的高级例子中看到。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;外部声明&lt;/font&gt; &lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Windows 编程中涉及的另一个重要元素是外部声明。外部声明原先用于在Pascal代码中连接汇编语言写的外部函数，现在外部声明用于Windows编程，用来调用动态连接库DLL函数。在Delphi的Windows 单元中有许多这种声明：&lt;/span&gt;&lt;/p&gt;&lt;em&gt;// forward declaration&lt;/em&gt;&lt;br/&gt;&lt;strong&gt;function &lt;/strong&gt;LineTo (DC: HDC; X, Y: Integer): BOOL; &lt;strong&gt;stdcall&lt;/strong&gt;;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;// external declaration (instead of actual code)&lt;/em&gt;&lt;br/&gt;&lt;strong&gt;function&lt;/strong&gt; LineTo; &lt;strong&gt;external&lt;/strong&gt; &lt;em&gt;'gdi32.dll'&lt;/em&gt; &lt;strong&gt;name&lt;/strong&gt; &lt;em&gt;'LineTo'&lt;/em&gt;;&lt;p class="MsoPlainText"&gt;这段声明表示函数&lt;span lang="EN-US"&gt;LineTo 的代码同名保存在GDI32.DLL 动态链接库中（最重要的Windows 系统库之一）。实际应用时，外部声明中的函数名与DLL中的函数名可以不同。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;一般你不需要象刚才所例举的那样写声明，因为&lt;span lang="EN-US"&gt;Windows 单元和一些Delphi 系统单元中已包含了这些声明。只有在调用自定义DLL，或调用Delphi 中未定义的Windows 函数时，你才能需要写外部声明。&lt;/span&gt;&lt;/p&gt;&lt;p class="note"&gt;&lt;strong&gt;注意：&lt;/strong&gt;在&lt;span lang="EN-US"&gt;16位Delphi中，外部声明使用不带扩展名的库名，后面跟name指令（如上所示）或是一个index指令，后面跟DLL中函数的序号。尽管Win32 仍然允许通过序号访问DLL函数，但是微软公司已经声明未来将不支持这种访问方式，这一改变反映了系统库访问方式的改变。还要注意的是:目前Delphi的Windows 单元已取代了16位Delphi的WinProcs 和WinTypes 单元。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;回调函数&lt;/font&gt; &lt;p class="MsoPlainText"&gt;从第六章已经了解到&lt;span lang="EN-US"&gt;Objet Pascal 支持过程类型。过程类型常用于给Windows API函数传递回调函数。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;首先，什么是回调函数呢？回调函数就是能对一系列系统内部元素执行给定操作的&lt;span lang="EN-US"&gt;API函数，例如能对所有同类窗口进行操作的函数。这种函数也叫枚举函数，它是作为参数传递的函数，代表对所有内部元素执行的操作，该函数或过程的类型必须与给定的过程类型兼容。Windows 回调函数的应用不止上述一种，不过这里仅研究以上简单应用。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;现在考虑&lt;span lang="EN-US"&gt; EnumWindows API 函数，它的原型如下（从Win32 帮助文件拷贝而来）：&lt;/span&gt;&lt;/p&gt;BOOL EnumWindows(&lt;br/&gt;  WNDENUMPROC lpEnumFunc,  &lt;em&gt;// address of callback function&lt;/em&gt;&lt;br/&gt;  LPARAM lParam &lt;em&gt;// application-defined value&lt;/em&gt;&lt;br/&gt;  );&lt;p class="MsoPlainText"&gt;当然，这是个&lt;span lang="EN-US"&gt;C语言的定义。我们可以查看Windows 单元，从中找到相应的Pascal 语言定义：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;function&lt;/strong&gt; EnumWindows (&lt;br/&gt;  lpEnumFunc: TFNWndEnumProc;&lt;br/&gt;  lParam: LPARAM): BOOL; &lt;strong&gt;stdcall&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;查阅帮助文件，我们发现作为参数传递的函数应该属于下面的类型（也是在&lt;span lang="EN-US"&gt;C中）：&lt;/span&gt;&lt;/p&gt;BOOL CALLBACK EnumWindowsProc (&lt;br/&gt;  HWND hwnd, &lt;em&gt;// handle of parent window&lt;/em&gt;&lt;br/&gt;  LPARAM lParam &lt;em&gt;// application-defined value&lt;/em&gt;&lt;br/&gt;  );&lt;p class="MsoPlainText"&gt;这与下面的&lt;span lang="EN-US"&gt;Delphi 过程类型定义一致：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;type&lt;/strong&gt;&lt;br/&gt;  EnumWindowsProc = &lt;strong&gt;function&lt;/strong&gt; (Hwnd: THandle;&lt;br/&gt;    Param: Pointer): Boolean; &lt;strong&gt;stdcall&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;其中第一个参数是各主窗体的句柄，第二个参数则是调用&lt;span lang="EN-US"&gt;EnumWindows 函数时所传递的值。实际上，Pascal 中没有相应的TFNWndEnumProc类型定义 ，它只是个指针。这意味着我们需要传递一个带有合适参数的函数，将它用作一个指针，也就是取函数的地址而不是调用它。不幸的是，这也意味着如果某个参数类型出现错误时，编译器不会给予提示。&lt;/span&gt;&lt;/p&gt;&lt;p class="note"&gt;每当调用&lt;span lang="EN-US"&gt;Windows API函数或传递一个回调函数给系统时，Windows 要求程序员遵循stdcall 调用协定。缺省情况下，Delphi使用另一种更高效的调用协定，其关键字为register。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;下面是一个与定义兼容的回调函数，此函数把窗口的标题读到字符串中，然后添加到给定窗体的一个列表框中：&lt;/p&gt;&lt;strong&gt;function&lt;/strong&gt; GetTitle (Hwnd: THandle; Param: Pointer): Boolean; &lt;strong&gt;stdcall&lt;/strong&gt;;&lt;br/&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;br/&gt;  Text: string;&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  SetLength (Text, 100);&lt;br/&gt;  GetWindowText (Hwnd, PChar (Text), 100);&lt;br/&gt;  FormCallBack.ListBox1.Items.Add (&lt;br/&gt;    IntToStr (Hwnd) + &lt;em&gt;': '&lt;/em&gt; + Text);&lt;br/&gt;  Result := True;&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;窗体有一个几乎覆盖整个窗体的列表框，窗体顶部有一个小面板，面板上有一个按钮。当按下按钮时，&lt;span lang="EN-US"&gt;EnumWindows API函数被调用，并且GetTitle 函数作为参数传递给它：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure&lt;/strong&gt; TFormCallback.BtnTitlesClick(Sender: TObject);&lt;br/&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;br/&gt;  EWProc: EnumWindowsProc;&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  ListBox1.Items.Clear;&lt;br/&gt;  EWProc := GetTitle;&lt;br/&gt;  EnumWindows (@EWProc, 0);&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;你可以直接调用GetTitle函数，不必先把值保存到过程类型临时变量中，上例这么做是为了使回调过程更清楚。程序运行结果确实很有意思，正如你在图&lt;span lang="EN-US"&gt;9.2中看到的那样，结果显示了系统中正在运行的所有主窗口，其中大部分是隐藏的，你通常看不到，许多实际上没有标题。&lt;/span&gt;&lt;/p&gt;&lt;p class="slug"&gt;图 9.2: 例CallBack输出结果--当前所有主窗体，其中包括可见及隐藏的窗体 &lt;p&gt;&lt;img border="0" alt="" src="http://www.cnblogs.com/jiangyuxuan/admin/mk:@MSITStore:F:/TDDOWNLOAD/Pascal%20精要(中文CHM格式）.chm::/epf0902.gif" width="304" height="352" /&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;最小的Windows 程序&lt;/font&gt; &lt;p class="MsoPlainText"&gt;为了完整介绍&lt;span lang="EN-US"&gt;Windows 编程及Pascal 语言，现在我展示一个简单但完整的应用程序，建立该程序没有使用VCL库。这个程序只是简单地采用命令行参数（保存在系统全程变量cmdLine中），并利用ParamCount 和 ParamStr 这两个Pascal 函数从参数中提取信息。其中第一个函数返回参数的个数，第二个返回给定位置的参数。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;尽管在图形用户界面环境下用户很少操纵命令行参数，但是&lt;span lang="EN-US"&gt;Windows 命令行参数对系统本身却很重要。例如，一旦你定义了文件扩展名和应用程序的关联，只要双击所关联的文件就能执行这个程序。实际上，当你双击一个文件，Windows 即启动关联程序并把选定的文件作为命令行参数传递给它。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;下面是工程文件的完整源代码（一个&lt;span lang="EN-US"&gt;DPR 文件，不是PAS 文件）：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;program&lt;/strong&gt; Strparam;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;uses&lt;/strong&gt;&lt;br/&gt;  Windows;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  &lt;em&gt;// show the full string&lt;/em&gt;&lt;br/&gt;  MessageBox (0, cmdLine, &lt;br/&gt;    &lt;em&gt;'StrParam Command Line'&lt;/em&gt;, MB_OK);&lt;br/&gt;&lt;br/&gt;  &lt;em&gt;// show the first parameter&lt;/em&gt;&lt;br/&gt;  &lt;strong&gt;if&lt;/strong&gt; ParamCount &amp;gt; 0 &lt;strong&gt;then&lt;/strong&gt;&lt;br/&gt;    MessageBox (0, PChar (ParamStr (1)), &lt;br/&gt;      &lt;em&gt;'1st StrParam Parameter'&lt;/em&gt;, MB_OK)&lt;br/&gt;  &lt;strong&gt;else&lt;/strong&gt;&lt;br/&gt;    MessageBox (0, PChar (&lt;em&gt;'No parameters'&lt;/em&gt;), &lt;br/&gt;      &lt;em&gt;'1st StrParam Parameter'&lt;/em&gt;, MB_OK);&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;.&lt;p class="MsoPlainText"&gt;输出代码使用&lt;span lang="EN-US"&gt;MessageBox API 函数，很容易就避开了VCL库。实际上，象上面那样纯粹的Windows 程序，其优点就是占的内存少，程序执行文件大约才16k字节。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;为了给程序提供命令行参数，你可以用&lt;span lang="EN-US"&gt;Delphi的 Run &amp;gt; Parameters 菜单命令。另一个方法是：打开Windows 资源管理器，查找包含程序执行文件的目录，然后把你要执行的文件拖到可执行文件上，Windows 资源管理器会把拖放的文件名用作命令行参数，开始执行程序。图9.3显示了资源管理器及相应的输出。&lt;/span&gt;&lt;/p&gt;&lt;p class="slug"&gt;图9.3: 把一个文件拖放到执行文件上，给例StrParam提供命令行参数 &lt;p&gt;&lt;img border="0" alt="" src="http://www.cnblogs.com/jiangyuxuan/admin/mk:@MSITStore:F:/TDDOWNLOAD/Pascal%20精要(中文CHM格式）.chm::/epf0903.gif" width="495" height="100" /&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;结束语&lt;/font&gt; &lt;p class="MsoPlainText"&gt;在这一章中，我们对&lt;span lang="EN-US"&gt;Windows 编程的底层内容进行了介绍，讨论了句柄和简单的Windows 程序。对于常规的Windows 编程任务，通常只需使用Delphi 提供的可视开发工具及VCL可视控件库。但是这超出了本书讨论的范围，因为本书讨论的是Pascal 语言。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;下一章介绍&lt;span lang="EN-US"&gt;variant类型。对Pascal 数据类型系统来说，它是一个非常特殊的外来物，引入它是为了提供完全的OLE 支持。&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jiangyuxuan/aggbug/2339914.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339914.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339913.html</id><title type="text">内存</title><summary type="text">Delphi 4 的动态数组 传统的Pascal 语言其数组大小是预先确定的，当你用数组结构声明数据类型时，你必须指定数组元素的个数。专业程序员也许知道些许动态数组的实现技术，一般是采用指针，用手工分配并释放所需的内存。Delphi 4中增加了非常简单的动态数组实现方法，实现过程效仿我前面讲过的动态长字符串。与长字符串一样，动态数组的内存动态分配并且引用记数，不过动态数组不支持 copy-on-write 技术。这不是个大问题，因为你可以把变量值设置为nil释放数组内存。这样你就可以声明一个不指定元素个数的数组，并用SetLength 过程给数组分配一个特定大小的内存，SetLength 过程</summary><published>2012-02-06T04:56:00Z</published><updated>2012-02-06T04:56:00Z</updated><author><name>江宇旋</name><uri>http://www.cnblogs.com/jiangyuxuan/</uri></author><link rel="alternate" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339913.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339913.html"/><content type="html">&lt;font color="#a52a2a" size="6" face="楷体_GB2312"&gt;Delphi 4 的动态数组&lt;/font&gt; &lt;p class="MsoPlainText"&gt;传统的&lt;span lang="EN-US"&gt;Pascal 语言其数组大小是预先确定的，当你用数组结构声明数据类型时，你必须指定数组元素的个数。专业程序员也许知道些许动态数组的实现技术，一般是采用指针，用手工分配并释放所需的内存。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Delphi 4中增加了非常简单的动态数组实现方法，实现过程效仿我前面讲过的动态长字符串。与长字符串一样，动态数组的内存动态分配并且引用记数，不过动态数组不支持 copy-on-write 技术。这不是个大问题，因为你可以把变量值设置为nil释放数组内存。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;这样你就可以声明一个不指定元素个数的数组，并用&lt;span lang="EN-US"&gt;SetLength 过程给数组分配一个特定大小的内存，SetLength 过程还可以改变数组大小而不影响其内容，除此外还有一些字符串过程也可用于数组，如Copy 函数。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoPlainText"&gt;以下摘录的代码突出了一点，这就是：定义数组后必须先为它分配内存，然后才能开始使用：&lt;/p&gt;&lt;strong&gt;procedure &lt;/strong&gt;TForm1.Button1Click(Sender: TObject);&lt;br/&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;br/&gt;  Array1: &lt;strong&gt;array of&lt;/strong&gt; Integer;&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  Array1 [1] := 100; &lt;em&gt;// error&lt;/em&gt;&lt;br/&gt;  SetLength (Array1, 100);&lt;br/&gt;  Array1 [99] := 100; &lt;em&gt;// OK&lt;/em&gt;&lt;br/&gt;  ...&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;如果你只定义一个数组元素个数，那么索引总是从&lt;span lang="EN-US"&gt;0开始。Pascal 中的普通数组既能用不为零的下标，也能用非整数的下标，但动态数组均不支持这两种下标。象普通数组一样，你可以通过Length、High和Low 函数了解到动态数组的状况，不过对于动态数组，Low 函数返回值总是0，High函数返回数组大小减1，这意味着空的动态数组其函数High返回值是-1，这是一个很怪的值，因为它比Low的返回值还小。&lt;/span&gt;&lt;/p&gt;&lt;p class="slug"&gt;图 8.1: 例 DynArr 窗体 &lt;/p&gt;&lt;p&gt;&lt;img border="0" alt="" src="http://www.cnblogs.com/jiangyuxuan/admin/mk:@MSITStore:F:/TDDOWNLOAD/Pascal%20精要(中文CHM格式）.chm::/epf0801.gif" width="203" height="166" /&gt; &lt;p class="MsoPlainText"&gt;以上作了简短的介绍，现在举个简例，例名&lt;span lang="EN-US"&gt;DynArr ，见图8.1。例子实在是很简单，其实动态数组没有什么特别复杂地方。我想通过该例说明几个程序员可能犯的错误。程序中声明了两个全程数组并在OnCreate 事件中初始化了第一个数组：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;br/&gt;  Array1, Array2: &lt;strong&gt;array of &lt;/strong&gt;Integer;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;procedure &lt;/strong&gt;TForm1.FormCreate(Sender: TObject);&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  &lt;em&gt;// allocate&lt;/em&gt;&lt;br/&gt;  SetLength (Array1, 100);&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;这样就把数组所有值设置为&lt;span lang="EN-US"&gt;0。完成这段代码你马上就能读写数组元素的值，而不用害怕内存出错，当然条件是你没有试图访问超过数组上界的元素。为了更好地初始化，程序中添加了一个按钮，执行数组元素赋值操作：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure &lt;/strong&gt;TForm1.btnFillClick(Sender: TObject);&lt;br/&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;br/&gt;  I: Integer;&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  &lt;strong&gt;for&lt;/strong&gt; I := Low (Array1) &lt;strong&gt;to&lt;/strong&gt; High (Array1) &lt;strong&gt;do&lt;/strong&gt;&lt;br/&gt;    Array1 [I] := I;&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Grow 按钮用于修改数组大小，但并不影响数组内容。单击Grow 按钮后，你可以用Get value按钮进行检验：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure &lt;/strong&gt;TForm1.btnGrowClick(Sender: TObject);&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;  // grow keeping existing values&lt;/em&gt;&lt;br/&gt;  SetLength (Array1, 200);&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;procedure&lt;/strong&gt; TForm1.btnGetClick(Sender: TObject);&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  &lt;em&gt;// extract&lt;/em&gt;&lt;br/&gt;  Caption := IntToStr (Array1 [99]);&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;Alias 按钮的OnClick 事件代码稍复杂些，程序通过 := 算子把一个数组拷贝给另一个数组，从而有效地创建了一个别名（一个新变量，但引用内存中同一数组）。从中可见，如果你改变了其中一个数组，那么另一个同样也会改变，因为它们指向同一个内存区：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure&lt;/strong&gt; TForm1.btnAliasClick(Sender: TObject);&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;  // alias&lt;/em&gt;&lt;br/&gt;  Array2 := Array1;&lt;br/&gt;&lt;em&gt;  // change one (both change)&lt;/em&gt;&lt;br/&gt;  Array2 [99] := 1000;&lt;br/&gt;&lt;em&gt;  // show the other&lt;/em&gt;&lt;br/&gt;  Caption := IntToStr (Array1 [99]);&lt;br/&gt;&lt;p class="MsoPlainText"&gt;在&lt;span lang="EN-US"&gt;btnAliasClick 事件中增加了两部分操作内容。第一部分是数组等同测试，不过并不是测试实际的数组元素，而是测试数组所引用的内存区，检测变量是不是内存中同一数组的两个别名：&lt;/span&gt;&lt;/p&gt;&lt;strong&gt;procedure&lt;/strong&gt; TForm1.btnAliasClick(Sender: TObject);&lt;br/&gt;&lt;strong&gt;begin&lt;/strong&gt;&lt;br/&gt;  ...&lt;br/&gt;  &lt;strong&gt;if&lt;/strong&gt; Array1 = Array2 &lt;strong&gt;then&lt;/strong&gt;&lt;br/&gt;    Beep;&lt;br/&gt;&lt;em&gt;  // truncate first array&lt;/em&gt;&lt;br/&gt;  Array1 := Copy (Array2, 0, 10);&lt;br/&gt;&lt;strong&gt;end&lt;/strong&gt;;&lt;p class="MsoPlainText"&gt;&lt;span lang="EN-US"&gt;btnAliasClick 事件的第二部分内容是调用Copy 函数。该函数不仅把数据从一个数组移到另一个数组，而且用函数创建的新数组取代第一个数组，结果变量Array1 所引用的是11个元素的数组，因此，按Get value 和Set value 按钮将产生一个内存错误，并且触发一个异常（除非你把范围检查range-checking 选项关掉，这种情况下，错误仍在但屏幕上不会显示异常）。虽然如此，Fill 按钮仍能正常工作，因为需要修改的数组元素由数组当前的下标范围确定。&lt;/span&gt;&lt;/p&gt;&lt;font color="brown" size="6" face="楷体_GB2312"&gt;结束语&lt;/font&gt; &lt;p class="MsoPlainText"&gt;这一章内容暂时只包括动态数组，动态数组的确是内存管理的重要组成部分，但仅仅是其中的一部分，其它内容以后会逐步添加。&lt;/p&gt;&lt;p class="MsoPlainText"&gt;本章描述的内存结构属于典型的 Windows 编程内容，这方面内容将在下一章进行讨论。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/jiangyuxuan/aggbug/2339913.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/jiangyuxuan/archive/2012/02/06/2339913.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
