Delphi 使用方法集 2007-12-25 13:48:00

关于Code Editor中的Diagram视图

1.和Object TreeView类似,Code Editor中的Diagram视图也是从Data Module中的类似概念发展而来的,
现在也从Data Module中分离出来,从而可以应用于所有的窗体。
2.Diagram视图不会自动显示任何构件。要显示某些构件,从Object TreeView中拖动你需要的构件到
Diagram视图中的白色区域即可(你可以从Object TreeView中一次拖动多个构件)。Diagram视图将会自动显示构件之间的所属关系。
例如,将Form和其上的构件拖动到Diagram视图中,那么视图中所有构件上都会出现指向Form的箭头,表明所有构件都为Form所拥有。 
3.可以用Diagram视图中的property connector来自动设置构件之间的一些关联。
例如,添加一个TEdit和一个TLabel,并用Diagram视图中工具栏上的property connector按钮来添加一个从TLabel指向TEdit的箭头,
你将会发现该箭头上自动出现FocusControl的字样,同时在Object Inspector中,Label的FocusControl被自动设置成了Edit1。
这一切之所以能够自动完成,是因为TLabel所有属性中唯一一个能够指向TEdit对象的就是FocusControl属性。
这样,你就可以形象化地设计对象之间的关联。反过来,你不能将property connector从Edit指向Label,
因为没有对应的属性可以完成这种关联;如果你试图这样做的话,你会得到一个错误提示,并询问你的意图是否为想要一个相反方向的关联。 
对于数据集构件,你还能够设置它们之间的Master/Detail关系和Lookup关系,其方法和上述步骤非常类似。
你还可以插入注释块(comment block),从而更明确的表达你的意图。 
4.Diagram视图可以进行修饰,从而更美观和明确。对于视图中每一个构件或者关联,都可以通过快捷菜单来设置它们的颜色和Z-Order顺序;
对于关联箭头,你还可以任意修改它的形状和指向,增加拐点等。
5.对同一单元可以使用多个Diagram。只要在Name文本框中输入它的名字,并且添加可选的描述信息即可。通过Diagram视图中工具栏上的组合框,
可以在各个Diagram之间切换。你可以为构件之间的Contains关系和数据表之间的关系分别建立Diagram,这样会更加清晰。
6.建立好一个满意的Diagram之后即可进行打印。只要让焦点保持在Diagram视图中,然后选择 File | Print 即可。
7.在Delphi 5中,Diagram信息是报存在单独的.DTI(design-time Information)中,该文件的格式和.INI文件的格式很类似,
可以用文本编辑器进行编辑。在Delphi 6中,Diagram信息则是保存在.DDP(Delphi Diagram Portfolio)文件中。
这种文件格式类似于.DFM的二进制格式,不能够直接编辑。不过,Delphi 6仍然能够读取.DTI文件。

关于VCL和CLX

Delphi 6 目前包括两个基本库,其中VCL是从Delphi诞生之日起就一直在使用的,
而CLX(Component Library for Cross-Platform)则是支持跨平台特性的新的构件库。
你可以从File | New选择使用的项目类型,可以为Normal Application或者CLX Application。
你会发现用VCL和CLX编写同样的应用程序,在产生的可执行文件大小方面会有一点小的差别。

当你选择VCL Application或者CLX Application的时候,构件面板也会发生相应的变化,只显示当前使用的库所支持的构件类型。
这种变化不算大,你要比较细心才能够发现。在CLX Application中,构件面板中的Win32页面消失了,
取而代之的是Common Controls,其中还包括几个Win32中没有的新构件。同时,其他页面也有一些小的变化。
对于用户来说,很少会注意到这些细节,但是这对于Delphi开发组来说是一个极大的挑战,因为系统的许多地方都需要重构以适应新的库。
应该说在这一点上Delphi开发组做的相当出色,Delphi从前版本的用户可以毫无困难的使用Delphi 6。
不过你应该知道,在类似的界面之下,底层的改变是相当巨大的—这对于特定的程序员,
例如编写 ToolsAPI的编程人员和其他一些有特定需要的人来讲,是必须要了解的内容。

其他的一些变化

Delphi IDE现在添加了一个Window菜单,从而可以方便的在Form Designer,Code Editor和Object TreeView/Object Inspector之间切换。
这是一个很小但非常体贴用户的改进,因为在开发环境中,经常发生某个窗口被其他窗口覆盖而找不到的事情。

(《Mastering Delphi 6》中提到,可以通过注册表中的Software\Borland\Delphi\6.0\Main Window表项来设置该菜单的显示或者隐藏,
其中-1代表True,而0代表False。不过在我的注册表中没有找到这个设置,不知道如何添加。如果你发现了的话,欢迎你告诉我。) 

构件面板的快捷菜单中现在添加了一个子菜单,其中包含了所有的面板名称。你可以用它来快速切换到某个面板中。
如果你经常不得不在面板中来回滚动以找到某个页面,你一定会非常欣赏这个新功能的。

(在默认情况下,这个快捷菜单中面板项目是按照字母顺序排列的。你可能会希望它按照在构件面板中同样的顺序来排列。
《Mastering Delphi6》中提到,可以设置注册表中的相应项目来修改这一行为。因为这一段说的表项不太明确,
由于时间关系我也没有进行试验,所以就把原文放在这里好了,大家感兴趣的话可以试试看。

The order of the entries in the Tabs submenu of the Component Palette local menu can be set in the same order as the palette itself, 
and not sorted alphabetically. This is accomplished by setting to “0” (false) the value of the Sort Palette Tabs Menu key of 
the Main Window registry section of Delphi (under \Software \Borland \Delphi \6.0 for the current user) 

其他还有一些细小的改动:
1.在Environment Options对话框中的Preference页面中新增一个选项Auto Drag Docking,允许你禁止各个工具的泊位特性。
如果你不喜欢Docking的话,你可以设置这一选项。(说实在的,我不知道《Mastering Delphi6》的作者为什么特别强调这个设置;
我自己是非常喜欢Docking的,我总是把Object Inspector和Object TreeView组合在一起,将Watch窗口Dock进入Code Editor中,
这样实在是方便不少。不过既然作者这么说,想必又他的理由,所以我还是尊重作者的意见,将这一点列为头条。)
2.在Environment Options对话框中新增一个Enviroment variables页面,允许设置系统环境变量。这样比硬编码某些路径来说好得多了,
特别是编写服务器应用的程序员可能会需要它。
3.新的Internet页面可以设置将哪些后缀名的文件视为Internet files,并且允许调试Scripts等。

关于To-do List:
除了可以在View | To-do List中可视化编辑之外,也可以在源文件中这样编辑:
procedure TForm1.FormCreate(Sender:TObject);
begin
//TODO -oMarco:Add creation code
end ;

这样将增加一个名为Add Creation code的项目,其Owner为Macro。如果你熟悉了这种方式的话,编辑起来会比用To-do List Editor更快捷
(当然,管理To-do List还是要用Editor)。-o指定Owner,-c指定Category,单独的一个数字指定priority。例如:
   // TODO 2 –oMacro : Mouse Pressed
如果一个To-do List已经完成,可以将TODO改成DONE来指明这一点。或者在To-do List Editor中选定Done检查框也可以。
指定为DONE的项目在To-do List中将显示为带删除线的形式。
你可以在to-do List Editor中将To-do List复制为纯文本或者HTML格式来进行输出,甚至可以指定HTML的输出格式
(不过有点奇怪的是,Delphi只提供了Copy to Clipboard的方式,却没有提供Export to File的功能。) 

代码编辑器是多页面形式(Multi-Page Interface)的,不过在Delphi 6中,这些页面还可以通过鼠标拖动来改变排列它们在代码编辑器中的顺序。
也可以通过Ctrl+Tab或者Shift+Ctrl+Tab在各个页面之间切换。在页面的快捷菜单中同样列出了编辑其中的所有页面,
当编辑其中打开的文件相当多时,可以通过这一功能快速切换到特定的文件(一个小而很方便的功能,和构件面板块接菜单中的Pages菜单一样非常有用。)

在Environment Options对话框中的AutoSave是一个很有用的选项,它可以在你运行程序或者调试程序之前,保存源文件,项目文件或者桌面设置,
从而避免调试过程中的意外崩溃导致数据丢失。(强烈建议至少选中Auto Save Editor Files;我很奇怪这为什么没有成为默认设置。)

2006-8-31 11:22:32   
 2007-1-13 10:51:09   
這些我都有試過了,都好好用。希望這些對大家有很大的幫助,
 
 2007-1-15 13:21:57   
这么好的资料,大家一定要进来看看啊,不看太可惜了哦,
 
 2007-1-30 12:55:11   
刷新一下,希望大家能看得到,
 
 2007-3-28 10:39:42   
這些我都有試過了,都好好用。希望這些對大家有很大的幫助,
 
 2007-4-18 12:39:32   
大家先看看這些筆記,以後我會繼續上傳的。謝謝大家光臨
 
 2007-6-3 11:09:10   
我的账号又找回来了.大家顶一下啊.
 
 2007-6-25 13:44:10    Delphi中ShellExecute的妙用
Delphi中ShellExecute的妙用
[轉載:]

ShellExecute的功能是运行一个外部程序(或者是打开一个已注册的文件、打开一个目录、打印一个文件等等),并对外部程序有一定的控制。
有几个API函数都可以实现这些功能,但是在大多数情况下ShellExecute是更多的被使用的,同时它并不是太复杂。下面举例说明它的用法。
开始一个新的应用程序 
ShellExecute(Handle, 'open', PChar('c:\test\app.exe'), nil, nil, SW_SHOW);
打开记事本,并打开一个文件(系统能识别记事本应用程序的路径,因此我们不必使用绝对路径)
ShellExecute(Handle, 'open', PChar('notepad'), PChar('c:\test\readme.txt'), nil, SW_SHOW);
打印一个文档
ShellExecute(Handle, 'print', PChar('c:\test\test.doc'), nil, nil, SW_SHOW);
注意:可能你会看到word暂时的被打开,但它会自动关闭。 
打开一个HTML页面 
ShellExecute(Handle, 'open', PChar('http://bbs.e-0631.cn'), nil, nil, SW_SHOW); 
你能通过一个已经注册的文件类型来打开应用程序 
ShellExecute(Handle, 'open', PChar('c:\test\readme.txt'), nil, nil, SW_SHOW); 
用windows Explorer 打开一个目录
ShellExecute(Handle, 'explore', PChar('c:\windows)', nil, nil, SW_SHOW);
运行一个DOS命令并立即返回
ShellExecute(Handle, 'open', PChar('command.com'), PChar('/c copy file1.txt file2.txt'), nil, SW_SHOW);
运行一个DOS命令并保持DOS窗口存在
ShellExecute(Handle, 'open', PChar('command.com'), PChar('/k dir'), nil, SW_SHOW);
ShellExecute详解
ShellExecute函数用于打开或者打印一个指定的文件。指定的文件必须是可执行文件或者文档文件。 
HINSTANCE ShellExecute(HWND hwnd, // handle to parent window 
LPCTSTR lpOperation, // pointer to string that specifies operation to perform
LPCTSTR lpFile, // pointer to filename or folder name string
LPCTSTR lpParameters, // pointer to string that specifies executable-file parameters  
LPCTSTR lpDirectory, // pointer to string that specifies default directory
INT nShowCmd  // whether file is shown when opened)

* Params(参数解释)
Hwnd 
指定父窗口句柄。这个窗口接收工程产生的所有消息。例如:一个工程可以通过消息框报告错误。 
lpOperation
以一个以null结束的字符串描述操作的执行。以下的操作字符串是有效的: 
行号 参数 含义 
1 “open” 函数打开由lpFile指定的文件。这个文件必须是可执行文件或者文档文件。文件夹必须是可打开的文件夹。
2 “print” 函数打印由lpFile指定的文件。这个文件应该是文档文件。如果指定的文件是可执行文件,函数将以open的方式打开这个文件。
3 “explore” 函数将搜索由lpFile指定的文件夹。
lpOperation参数如果为null,函数将以open的方式打开由lpFile指定的文件。 
lpFile
以一个null结束的字符串描述打开或者打印指定的文件,或者打开或者搜索指定的 文件夹。函数可以打开一个指定的文件或者文件夹,也可以打印一个文档文件。
lpParameters
如果lpFile指定的是一个可执行文件,lpParameters以一个以null结束的字符串指定该执行文件传给应用软件的参数。
行号 参数 含义
1 SW_HIDE 隐藏这个窗体,并激活其他窗体。
2 SW_MAXIMIZE 最大化指定的窗体。
3 SW_MINIMIZE 最小化指定的窗体,并按顺序激活最上层的窗体。
4 SW_RESTORE 激活并显示窗体。如果窗体为最小化或者最大化,窗体恢复到原始大小和位置。应用程序当恢复一个最小化的窗体时将指定标记。
5 SW_SHOW 以当前的大小和位置激活并显示窗体。
6 SW_SHOWDEFAULT
7 SW_SHOWMAXIMIZED 激活并最大化显示窗体。
8 SW_SHOWMINIMIZED 激活并最小化现实窗体。
9 SW_SHOWMINNOACTIVE 最小化窗体,保持其激活状态。
10 SW_SHOWNA 以当前状态显示窗体,保持其激活状态。
11 SW_SHOWNOACTIVATE 以当前的大小和位置显示窗体,并保持其激活状态。
12 SW_SHOWNORMAL 激活并显示一个窗体。如果窗体为最大化或者最小化,窗体恢复到原始的大小和位置。当窗体第一次显示的时候,应用程序记录标记。
如果lpField指定的是一个文档文件,lpParameters应该为null。
lpDirectory
以一个以null结束的字符串指定文件开始运行的默认目录。
nShowCmd
如果lpField指定了一个可执行文件,nShowCmd指定这个文件在被打开时如何显示。这个参数可以是以下值中的任何一个:
如果lpField指定的是文档文件,nShowCmd应该为0。
* return Values(返回值)
如果函数执行成功,返回值是已经运行的工程的实例句柄,或者动态数据交换服务器应用程序的句柄。
(具体返回值列表从略,请参考Delphi在线帮助)
* Remarks(注释)
被lpFile参数指定的文件必须是一个可执行文件或者文档文件。如果文件是一个文档文件,ShellExecute函数将根据lpOperation参数决定打开或者打印这个文件。如果是可执行文件,ShellExecute函数将打开它,即使lpOperation参数被指定为printing。
你可以使用ShellExecute打开活着搜索一个文件夹。可以使用以下任意一种方式打开一个文件夹:
ShellExecute(handle, NULL, path_to_folder, NULL, NULL, SW_SHOWNORMAL);
或者 ShellExecute(handle, "open", path_to_folder, NULL, NULL, SW_SHOWNORMAL);
使用下面的调用搜索文件夹:
ShellExecute(handle, "explore", path_to_folder, NULL, NULL, SW_SHOWNORMAL)
如果lpOperation参数为null,函数将打开由lpFile指定的文件。如果lpOperation参数为”open”或者”explore”,函数将强制打开窗体或者资源管理器。
注:在新窗口打开网页的办法
 ShellExecute(self.Handle, PChar('open'), PChar('explorer'), PChar(URL), nil, SW_MAXIMIZE); 
 Q: 如何打开一个应用程序?
 ShellExecute(this->m_hWnd,"open","calc.exe","","", SW_SHOW) ;
 或 ShellExecute(this->m_hWnd,"open","notepad.exe",
 "c:\MyLog.log","",SW_SHOW);
 Q: 如何打开一个同系统程序相关连的文档?
 ShellExecute(this->m_hWnd,"open", "c:\abc.txt","","",SW_SHOW);
 Q: 如何打开一个网页?
 ShellExecute(this->m_hWnd,"open","http://bbs.e-0631.cn";,"","",  SW_SHOW);
 Q: 如何激活相关程序,发送EMAIL?
 ShellExecute(this->m_hWnd,"open","mailto:nishinapp@yahoo.com","","", SW_SHOW);
 Q: 如何用系统打印机打印文档?
 ShellExecute(this->m_hWnd,"print","c:\abc.txt","","", SW_HIDE);
 Q: 如何用系统查找功能来查找指定文件?
 ShellExecute(m_hWnd,"find","d:\nish", NULL,NULL,SW_SHOW);
 Q: 如何启动一个程序,直到它运行结束?
 SHELLEXECUTEINFO ShExecInfo = {0};
 ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
 ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
 ShExecInfo.hwnd = NULL;
 ShExecInfo.lpVerb = NULL;
 ShExecInfo.lpFile = "c:\MyProgram.exe"; 
 ShExecInfo.lpParameters = ""; 
 ShExecInfo.lpDirectory = NULL;
 ShExecInfo.nShow = SW_SHOW;
 ShExecInfo.hInstApp = NULL;
 ShellExecuteEx(&ShExecInfo);
 WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
 或:PROCESS_INFORMATION ProcessInfo; 
 STARTUPINFO StartupInfo; //入口参数
 ZeroMemory(&StartupInfo, sizeof(StartupInfo));
 StartupInfo.cb = sizeof StartupInfo ; //分配大小
 if(CreateProcess("c:\winnt\notepad.exe", NULL, 
 NULL,NULL,FALSE,0,NULL,
 NULL,&StartupInfo,&ProcessInfo))
 {WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
 CloseHandle(ProcessInfo.hThread);
 CloseHandle(ProcessInfo.hProcess);
 }
 else
 {
 MessageBox("The process could not be started...");
 }
 Q: 如何显示文件或文件夹的属性?
 SHELLEXECUTEINFO ShExecInfo ={0};
 ShExecInfo.cbSize = sizeof
 SHELLEXECUTEINFO);
 ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST ;
 ShExecInfo.hwnd = NULL;
 ShExecInfo.lpVerb = "properties";
 ShExecInfo.lpFile = "c:\"; //也可以是文件
 ShExecInfo.lpParameters = ""; 
 ShExecInfo.lpDirectory = NULL;
 ShExecInfo.nShow = SW_SHOW;
 ShExecInfo.hInstApp = NULL
 
 2007-6-25 13:58:01    制作自启动光盘的方法
制作自启动光盘的方法
[轉載]

在刻录光盘时加入一个文件:autorun.INF
autorun.INF的内容如下:[AutoRun]
open=autorun.exe
icon=autorun.exe
用意解释:
////////////////////////////////

[AutoRun]
open=autorun.exe//autorun.exe是你要运行的文件名字,可能是setup.exe等
icon=autorun.exe//是光盘的图标,可以单独放置一个图标文件,如ico,插入光盘后,原光盘图标将显示为此文件的图标
设置光盘的自动运行特征: 
procedure  TForm1.SetCDAutoRun(AAutoRun:Boolean);
const
DoAutoRun  :  array[Boolean]  of  Integer  =  (0,1);
var
Reg  :  TRegistry;
begin
try
{  create  our  registry  object  }
Reg  :=  TRegistry.Create;

{  set  our  registry  root  key  }
Reg.RootKey  :=  HKEY_LOCAL_MACHINE;
{  verify  that  our  CDROM  class  key  exists  }
if  Reg.KeyExists('System')  then
{  try  to  open  our  CDROM  class  key  }
if  Reg.OpenKey('System',FALSE)  then
{  add  AutoRun  to  our  CDROM  class  key  }
Reg.WriteBinaryData('AutoRun',DoAutoRun[AAutoRun],1);
finally
{  free  our  registry  object  }
Reg.Free;
end;
{  showmessage  that  the  changes  will  happen  on  reboot  }
ShowMessage('Your  settings  will  take  effect  on  the  next  reboot  of  Windows.');
en   
 
 2007-6-27 12:29:56    通用函数,得到汉字笔画!
通用函数,得到汉字笔画!
[轉]

function GetBiHua(chnstr:string):integer;
const
  BiHuaTable=
     #10#7#10#10#8#10#9#11#17#14#13#5#13#10#12#15+
     #10#6#10#9#12#8#10#10#8#8#10#5#10#14#16#9+
     #12#12#15#15#7#10#5#5#7#10#2#9#4#8#12#13+
     #7#10#7#21#10#8#5#9#6#13#8#8#9#13#12#10+
     #13#7#10#10#8#8#7#8#7#19#5#4#8#6#9#10+
     #14#14#9#12#15#10#15#12#12#8#9#5#15#10#16#13+
     #9#12#8#8#8#7#15#10#13#19#8#13#12#8#5#12+
     #9#4#9#10#7#8#12#12#10#8#8#5#11#11#11#9+
     #9#18#9#12#14#4#13#10#8#14#13#14#6#10#9#4+
     #7#13#6#11#14#5#13#16#17#16#9#18#5#12#8#9+
     #9#8#4#16#16#17#12#9#11#15#8#19#15#7#15#11+
     #12#16#13#10#13#7#6#9#5#8#9#9#10#6#9#11+
     #15#8#10#8#12#9#13#10#14#7#8#11#11#14#12#8+
     #7#10#2#10#7#11#4#5#7#19#10#8#17#11#12#7+
     #3#7#13#15#8#11#11#14#16#8#10#9#11#11#7#7+
     #10#4#7#17#16#16#15#11#9#8#12#8#5#9#7#19+
     #12#3#9#9#9#14#12#14#7#9#8#8#10#10#12#11+
     #11#12#11#13#11#6#11#19#8#11#6#9#11#4#11#7+
     #2#12#8#11#10#12#7#9#12#15#15#11#7#8#4#7+
     #15#12#7#15#10#6#7#6#11#7#7#7#12#8#15#10+
     #9#16#6#7#8#12#12#15#8#8#10#10#10#6#13#9+
     #11#6#7#6#6#10#8#8#4#7#10#5#9#6#6#6+
     #11#8#8#13#12#14#13#13#13#4#11#14#4#10#7#5+
     #16#12#18#12#13#12#9#13#10#12#24#13#13#5#12#3+
     #9#13#6#11#12#7#9#12#15#7#6#6#7#8#11#13+
     #8#9#13#15#10#11#7#21#18#11#11#9#14#14#13#13+
     #10#7#6#8#12#6#15#12#7#5#4#5#11#11#15#14+
     #9#19#16#12#14#11#13#10#13#14#11#14#7#6#3#14+
     #15#12#11#10#13#12#6#12#14#5#3#7#4#12#17#9+
     #9#5#9#11#9#11#9#10#8#4#8#10#11#9#5#12+
     #7#11#11#8#11#11#6#9#10#9#10#2#10#17#10#7+
     #11#6#8#15#11#12#11#15#11#8#19#6#12#12#17#14+
     #4#12#7#14#8#10#11#7#10#14#14#7#8#6#12#11+
     #9#7#10#12#16#11#13#13#9#8#16#9#5#7#7#8+
     #11#12#11#13#13#5#16#10#2#11#6#8#10#12#10#14+
     #15#8#11#13#2#7#5#7#8#12#13#8#4#6#5#5+
     #12#15#6#9#8#9#7#9#11#7#4#9#7#10#12#10+
     #13#9#12#9#10#11#13#12#7#14#7#9#12#7#14#12+
     #14#9#11#12#11#7#4#5#15#7#19#12#10#7#9#9+
     #12#11#9#6#6#9#13#6#13#11#8#12#11#13#10#12+
     #9#15#6#10#10#4#7#12#11#10#10#6#2#6#5#9+
     #9#2#9#5#9#12#6#4#9#8#9#18#6#12#18#15+
     #8#8#17#3#10#4#7#8#8#5#7#7#7#7#4#8+
     #8#6#7#6#6#7#8#11#8#11#3#8#10#10#7#8+
     #8#8#9#7#11#7#8#4#7#7#12#7#10#8#6#8+
     #12#12#4#9#8#13#10#12#4#9#11#10#5#13#6#8+
     #4#7#7#4#15#8#14#7#8#13#12#9#11#6#9#8+
     #10#11#13#11#5#7#7#11#10#10#8#11#12#8#14#9+
     #11#18#12#9#12#5#8#4#13#6#12#4#7#6#13#8+
     #15#14#8#7#13#9#11#12#3#5#7#9#9#7#10#13+
     #8#11#21#4#6#9#9#7#7#7#12#7#16#10#10#14+
     #10#16#13#15#15#7#10#14#12#4#11#10#8#12#9#12+
     #10#12#9#12#11#3#6#9#10#13#10#7#8#19#10#10+
     #11#3#7#5#10#11#8#10#4#9#3#6#7#9#7#6+
     #9#4#7#8#8#9#8#8#11#12#11#8#14#7#8#8+
     #8#13#5#11#9#7#8#9#10#8#12#8#5#9#14#9+
     #13#8#8#8#12#6#8#9#6#14#11#23#11#20#8#6+
     #3#10#13#8#6#11#5#7#9#6#9#8#9#10#8#13+
     #9#8#12#13#12#12#10#8#8#14#6#9#15#9#10#10+
     #6#10#9#12#15#7#12#7#11#12#8#12#7#16#16#10+
     #7#16#10#11#6#5#5#8#10#17#17#14#11#9#6#10+
     #5#10#8#12#10#11#10#5#8#7#6#11#13#9#8#11+
     #14#14#15#9#15#12#11#9#9#9#10#7#15#16#9#8+
     #9#10#9#11#9#7#5#6#12#9#12#7#9#10#6#8+
     #5#8#13#10#12#9#15#8#15#12#8#8#11#7#4#7+
     #4#7#9#6#12#12#8#6#4#8#13#9#7#11#7#6+
     #8#10#7#12#10#11#10#12#13#11#10#9#4#9#12#11+
     #16#15#17#9#11#12#13#10#13#9#11#6#9#12#17#9+
     #12#6#13#10#15#5#12#11#10#11#6#10#5#6#9#9+
     #9#8#11#13#9#11#17#9#6#4#10#8#12#16#8#11+
     #5#6#11#6#13#15#10#14#6#5#9#16#4#7#10#11+
     #12#6#7#12#13#20#12#3#9#10#6#7#13#6#9#2+
     #10#3#13#7#16#8#6#11#8#11#9#11#11#4#5#9+
     #7#7#7#10#6#14#9#6#8#10#5#9#12#10#5#10+
     #11#15#6#9#8#13#7#10#7#6#11#7#13#10#8#8+
     #6#12#9#11#9#14#12#8#10#13#9#11#11#9#14#13+
     #12#9#4#13#15#6#10#10#9#8#11#12#12#8#15#9+
     #9#10#6#19#12#10#9#6#6#13#8#15#12#17#12#10+
     #6#8#9#9#9#20#12#11#11#8#11#9#7#9#16#9+
     #13#11#14#10#10#5#12#12#11#9#11#12#6#14#7#5+
     #10#8#11#13#14#9#9#13#8#7#17#7#9#10#4#9+
     #9#8#3#12#4#8#4#9#18#10#13#4#13#7#13#10+
     #13#7#10#10#6#7#9#14#8#13#12#16#8#11#14#13+
     #8#4#19#12#11#14#14#12#16#8#10#13#11#10#8#9+
     #12#12#7#5#7#9#3#7#2#10#11#11#5#6#13#8+
     #12#8#17#8#8#10#8#8#11#7#8#9#9#8#14#7+
     #11#4#8#11#15#13#10#5#11#8#10#10#12#10#10#11+
     #8#10#15#23#7#11#10#17#9#6#6#9#7#11#9#6+
     #7#10#9#12#10#9#10#12#8#5#9#4#12#13#8#12+
     #5#12#11#7#9#9#11#14#17#6#7#4#8#6#9#10+
     #15#8#8#9#12#15#14#9#7#9#5#12#7#8#9#10+
     #8#11#9#10#7#7#8#10#4#11#7#3#6#11#9#10+
     #13#8#14#7#12#6#9#9#13#10#7#13#8#7#10#12+
     #6#12#7#10#8#11#7#7#3#11#8#13#12#9#13#11+
     #12#12#12#8#8#10#7#9#6#13#12#8#8#12#14#12+
     #14#11#10#7#13#13#11#9#8#16#12#5#15#14#12#9+
     #16#12#9#13#11#12#10#11#8#10#10#10#7#7#6#8+
     #9#13#10#10#11#5#13#18#16#15#11#17#9#16#6#9+
     #8#12#13#7#9#11#11#15#16#10#10#13#11#7#7#15+
     #5#10#9#6#10#7#5#5#10#4#7#12#8#9#12#5+
     #11#7#8#2#14#10#9#12#10#7#18#13#8#10#8#11+
     #11#12#10#9#8#13#10#11#13#7#7#11#12#12#9#10+
     #15#11#14#7#16#14#5#15#2#14#17#14#10#6#12#10+
     #6#11#12#8#17#16#9#7#20#11#15#10#7#8#9#11+
     #13#13#10#7#11#10#7#10#8#11#5#5#13#11#14#12+
     #13#10#6#15#10#9#4#5#11#8#11#16#11#8#8#7+
     #13#9#12#12#14#8#7#5#11#7#8#11#7#8#12#19+
     #13#21#13#10#11#16#11#8#7#15#7#6#11#8#10#15+
     #12#12#10#12#9#11#13#11#9#10#9#13#7#7#11#11+
     #7#8#6#4#7#7#6#11#17#8#11#13#14#14#13#12+
     #9#9#9#6#11#7#8#9#3#9#14#6#10#6#7#8+
     #6#9#15#14#12#13#14#11#14#14#13#6#9#8#8#6+
     #10#11#8#13#4#5#10#5#8#9#12#14#9#3#8#8+
     #11#14#15#13#7#9#12#14#7#9#9#12#8#12#3#7+
     #5#11#13#17#13#13#11#11#8#11#16#19#17#9#11#8+
     #6#10#8#8#14#11#12#12#10#11#11#7#9#10#12#9+
     #8#11#13#17#9#12#8#7#14#5#5#8#5#11#10#9+
     #8#16#8#11#6#8#13#13#14#19#14#14#16#15#20#8+
     #5#10#15#16#8#13#13#8#11#6#9#8#7#7#8#5+
     #13#14#13#12#14#4#5#13#8#16#10#9#7#9#6#9+
     #7#6#2#5#9#8#9#7#10#22#9#10#9#8#11#8+
     #10#4#14#10#8#16#10#8#5#7#7#10#13#9#13#14+
     #8#6#15#15#11#8#10#14#5#7#10#10#19#11#15#15+
     #10#11#9#8#16#5#8#8#4#7#9#7#10#9#6#7+
     #5#7#9#3#13#9#8#9#17#20#10#10#8#9#8#18+
     #7#11#7#11#9#8#8#8#12#8#11#12#11#12#9#19+
     #15#11#15#9#10#7#9#6#8#10#16#9#7#8#7#9+
     #10#12#8#8#9#11#14#12#10#10#8#7#12#9#10#8+
     #11#15#12#13#12#13#16#16#8#12#11#13#8#9#21#7+
     #8#15#12#9#11#12#10#5#4#12#15#7#20#15#11#4+
     #12#15#14#16#11#14#16#9#13#8#9#13#6#8#8#11+
     #5#8#10#7#9#8#8#11#11#10#14#8#11#10#5#12+
     #4#10#12#11#13#10#6#10#12#10#14#19#18#12#12#10+
     #11#8#2#10#14#9#7#8#12#8#7#11#11#10#6#14+
     #8#6#11#10#6#3#6#7#9#9#16#4#6#7#7#8+
     #5#11#9#9#9#6#8#10#3#6#13#5#12#11#16#10+
     #10#9#15#13#8#15#11#12#4#14#8#7#12#7#14#14+
     #12#7#16#14#14#10#10#17#6#8#5#16#15#12#10#9+
     #10#4#8#5#8#9#9#9#9#10#12#13#7#15#12#13+
     #7#8#9#9#10#10#11#16#12#12#11#8#10#6#12#7+
     #9#5#7#11#7#5#9#8#12#4#11#6#11#8#7#11+
     #8#11#17#15#5#11#23#6#16#9#6#11#10#4#8#4+
     #10#8#16#7#13#14#12#11#12#13#12#16#5#9#22#20+
     #20#20#5#9#7#9#12#10#4#4#2#7#7#6#4#3+
     #7#6#5#4#4#6#9#13#9#16#14#13#10#9#4#12+
     #9#6#9#20#16#17#6#10#8#6#2#15#8#6#15#13+
     #12#7#10#8#10#15#9#11#13#17#13#14#3#8#6#12+
     #10#13#8#12#12#6#12#13#6#10#12#14#10#9#6#8+
     #7#7#13#11#13#12#10#9#8#7#3#7#14#8#5#8+
     #16#17#16#12#6#10#15#14#6#11#12#10#3#8#14#11+
     #10#12#10#6#3#14#4#10#7#8#11#11#11#6#8#11+
     #13#10#13#10#7#6#10#5#8#7#7#11#10#8#9#7+
     #8#11#9#8#13#11#7#5#12#9#4#11#9#11#12#9+
     #5#6#5#9#9#12#8#3#8#2#5#9#7#4#9#9+
     #8#7#5#5#8#9#8#8#6#5#3#5#9#8#9#14+
     #10#8#9#13#16#9#5#8#12#8#4#5#9#9#8#8+
     #6#4#9#6#7#11#11#8#14#11#15#8#11#10#7#13+
     #8#12#11#12#4#12#11#15#16#12#17#13#13#12#13#12+
     #5#8#9#7#6#9#14#11#13#14#10#8#9#14#10#5+
     #5#10#9#17#4#11#10#4#13#12#7#17#9#12#9#11+
     #10#8#12#15#15#9#7#5#5#6#13#6#13#5#7#6+
     #8#3#8#10#8#10#9#7#6#9#12#15#16#14#7#12+
     #9#10#10#12#14#13#13#11#7#8#14#13#14#9#11#11+
     #10#21#13#6#17#12#14#10#6#10#10#13#11#10#14#11+
     #10#12#8#13#5#5#6#12#16#9#17#15#9#8#8#5+
     #10#11#4#8#7#7#13#8#15#13#7#17#13#15#14#10+
     #8#12#10#14#11#5#9#6#13#13#11#12#15#10#16#10+
     #15#11#15#10#11#10#13#10#11#10#9#11#10#5#10#10+
     #18#13#10#13#11#10#15#12#12#15#16#12#7#12#17#11+
     #10#9#8#4#11#13#5#11#9#14#12#9#7#8#11#13+
     #9#10#8#4#7#9#5#6#11#9#9#9#12#10#10#13+
     #17#6#11#7#12#11#10#12#9#12#11#7#5#10#5#7+
     #9#8#10#10#10#11#3#6#8#12#6#11#13#13#13#13+
     #9#7#4#17#8#6#11#10#7#6#8#12#7#8#11#9+
     #9#12#9#9#4#10#9#5#15#9#12#8#10#3#11#7+
     #13#10#11#12#11#8#11#3#12#7#4#3#8#6#8#8+
     #11#7#6#9#20#13#6#4#7#10#7#11#11#4#14#11+
     #7#11#8#6#6#7#7#5#14#8#9#9#12#17#7#12+
     #11#11#15#3#14#12#10#4#9#7#7#14#10#6#13#10+
     #8#9#13#10#12#7#14#8#12#7#7#7#9#4#6#9+
     #9#4#7#11#7#7#4#8#4#10#4#14#6#9#7#5+
     #13#11#8#4#5#10#9#8#14#8#6#11#8#12#15#6+
     #13#10#12#10#7#11#15#3#11#14#11#13#6#12#17#11+
     #10#3#13#12#11#9#7#12#6#8#15#9#7#17#14#13+
     #9#8#9#3#12#10#6#11#13#6#5#14#6#9#8#11+
     #11#7#9#8#13#9#9#8#13#7#13#11#12#9#10#8+
     #8#9#11#22#9#15#17#12#3#12#10#8#13#9#8#9+
     #9#15#13#6#11#11#12#15#9#10#18#12#10#10#11#10+
     #3#7#10#7#11#10#10#13#8#13#15#15#6#9#13#6+
     #11#8#11#5#11#9#19#16#8#8#12#10#16#7#12#8+
     #7#13#7#4#9#11#9#13#12#12#6#6#9#7#6#6+
     #16#8#7#8#8#5#4#10#6#7#12#14#6#9#10#6+
     #13#12#7#10#10#14#6#14#11#14#9#10#6#13#11#9+
     #6#7#10#9#12#12#11#11#7#12#9#11#11#5#9#19+
     #10#9#13#16#8#5#11#6#9#14#12#6#8#6#6#6+
     #10#6#5#5#9#6#6#8#9#10#7#3#7#4#10#11+
     #13#11#12#9#6#6#11#9#11#10#11#10#7#9#12#8+
     #6#7#15#11#8#8#8#11#11#9#14#10#12#16#6#9+
     #12#10#9#12#10#11#10#9#5#10#10#7#6#8#8#6+
     #9#6#10#6#11#9#10#14#16#13#7#14#13#6#13#11+
     #12#9#9#10#9#9#20#12#15#8#6#11#7#3#6#11+
     #5#5#6#12#8#11#1#12#7#12#11#8#6#6#13#6+
     #12#11#5#10#14#7#8#9#18#12#9#10#3#1#7#4+
     #4#7#8#7#6#3#7#17#11#13#9#6#13#13#15#4+
     #3#10#13#8#5#10#7#6#17#11#8#9#9#6#10#9+
     #6#9#7#11#11#11#7#4#4#11#5#8#15#11#18#7+
     #14#10#11#11#9#14#7#17#9#15#13#10#9#9#8#7+
     #17#10#11#13#14#13#8#8#10#5#11#9#5#9#6#11+
     #7#4#5#7#10#7#8#12#7#6#4#5#7#12#9#2+
     #5#6#11#3#8#13#13#13#14#7#9#12#8#12#12#11+
     #11#4#10#8#3#6#9#6#9#6#5#11#6#8#6#12+
     #12#10#12#13#11#9#8#13#10#12#12#10#15#5#10#11+
     #10#4#9#10#10#12#14#7#7#10#13#13#12#7#8#14+
     #9#9#4#6#12#11#9#8#12#4#10#10#10#4#9#4+
     #9#4#7#15#11#10#13#5#5#10#6#10#9#7#10#10+
     #6#6#9#19#12#16#10#10#12#14#17#12#19#8#6#16+
     #9#20#16#10#7#7#17#8#8#6#8#10#9#15#15#12+
     #16#4#12#12#5#5#11#8#9#9#14#8#5#9#7#14+
     #10#6#10#10#14#18#9#13#11#8#10#8#14#11#10#22+
     #9#5#9#10#12#11#15#11#14#14#7#12#10#7#3#7+
     #8#5#8#16#13#8#9#7#8#9#13#13#6#14#5#14+
     #7#10#12#16#8#13#14#7#10#9#13#10#13#10#16#6+
     #7#8#8#10#7#15#10#15#6#13#9#11#8#9#6#8+
     #16#9#5#9#9#10#8#7#6#8#4#7#14#8#8#10+
     #5#3#8#11#8#12#12#6#10#8#7#9#4#11#5#6+
     #7#7#10#11#6#10#13#8#9#8#12#10#13#8#8#11+
     #12#8#11#4#9#8#9#10#8#9#8#9#6#6#6#8+
     #6#9#7#12#9#7#8#8#10#8#9#17#10#10#12#6+
     #11#10#8#10#6#10#12#8#17#15#5#11#9#7#11#8+
     #12#12#7#8#9#8#7#4#9#4#9#8#15#14#15#10+
     #6#12#6#15#6#7#12#13#9#14#7#11#10#10#10#8+
     #8#10#12#8#10#11#11#7#9#9#9#10#9#12#11#7+
     #12#5#9#13#3#6#11#6#18#12#15#8#11#9#7#7+
     #7#9#12#10#7#8#11#9#7#7#8#10#20#16#15#12+
     #13#12#15#9#5#7#9#11#7#7#10#0#0#0#0#0+
     #3#3#3#4#4#4#5#6#6#10#10#16#0#9#0#2+
     #3#4#4#5#5#6#9#11#14#14#19#0#8#14#2#6+
     #4#7#7#11#14#4#6#10#11#12#14#15#16#0#5#8+
     #11#11#15#8#7#0#4#6#7#8#8#8#9#10#10#10+
     #13#13#14#14#15#16#0#8#0#4#4#4#5#5#5#5+
     #6#6#6#6#6#6#6#6#6#7#7#7#7#7#7#7+
     #7#7#8#8#8#8#8#8#8#8#8#8#8#8#9#9+
     #9#9#9#9#9#9#9#10#10#10#10#10#10#10#10#10+
     #10#10#10#10#11#11#11#11#11#11#11#12#12#12#13#14+
     #14#14#14#14#14#15#15#5#6#7#7#8#17#6#8#4+
     #12#16#17#18#21#0#9#9#11#6#6#7#0#8#10#10+
     #11#12#12#12#13#16#19#19#0#6#8#8#10#0#10#10+
     #0#5#5#5#6#6#6#7#7#7#7#7#7#8#8#8+
     #8#8#8#8#8#8#8#8#9#9#9#9#10#10#10#10+
     #10#10#10#11#11#11#11#11#11#11#11#11#11#11#12#12+
     #12#12#12#13#13#14#14#14#15#15#19#0#8#0#5#5+
     #6#6#7#7#7#7#8#9#9#10#10#10#11#11#11#16+
     #5#5#5#5#6#6#7#7#7#7#7#7#8#8#8#8+
     #8#8#8#9#9#9#9#9#10#10#11#11#13#13#13#14+
     #14#16#19#20#5#7#5#7#7#8#10#10#11#15#9#17+
     #20#0#0#6#10#2#5#10#12#7#9#9#14#16#16#17+
     #6#6#6#6#6#6#6#7#7#7#8#8#8#8#8#8+
     #8#8#8#8#9#9#9#9#9#9#9#9#9#10#10#10+
     #10#10#10#11#11#11#11#11#11#11#11#11#11#12#12#12+
     #12#13#13#14#14#14#15#20#21#22#0#5#5#6#6#6+
     #6#6#6#6#7#7#7#7#7#7#7#7#7#7#7#7+
     #7#7#7#7#7#7#7#7#7#7#7#8#8#8#8#8+
     #8#8#8#8#8#8#8#8#8#8#8#8#8#8#9#9+
     #9#9#9#9#9#9#9#9#9#9#9#9#9#9#9#9+
     #9#9#9#9#9#9#9#9#9#9#9#9#9#10#10#10+
     #10#10#10#10#10#10#10#10#10#10#10#10#10#10#10#10+
     #10#11#11#11#11#11#11#11#11#11#11#11#11#11#11#11+
     #11#11#11#11#11#11#11#11#11#11#11#12#12#12#12#12+
     #12#12#12#12#12#12#12#12#12#12#12#12#12#13#13#13+
     #13#13#13#13#13#13#13#13#13#13#13#13#13#14#14#14+
     #14#14#14#14#14#14#14#14#15#15#15#15#15#15#15#15+
     #15#16#16#16#16#16#16#16#16#16#17#17#17#17#17#18+
     #19#19#19#20#20#22#0#9#6#7#9#9#10#10#11#0+
     #6#7#13#0#6#7#8#8#8#8#9#9#9#10#10#10+
     #11#11#11#11#11#11#11#11#11#11#11#11#12#12#12#12+
     #12#12#12#12#12#12#13#13#13#13#13#13#13#13#14#14+
     #14#14#14#15#15#15#15#16#16#16#17#17#19#23#25#3+
     #7#8#12#5#5#5#5#5#5#6#6#6#7#7#7#7+
     #7#7#7#7#7#7#7#8#8#8#8#8#8#8#8#8+
     #8#8#9#9#9#9#9#9#9#9#9#9#9#9#9#9+
     #9#9#9#9#9#9#9#9#9#9#10#10#10#10#10#10+
     #10#10#10#10#10#11#11#11#11#11#11#11#11#11#11#11+
     #11#11#11#11#11#11#11#11#12#12#12#12#12#12#12#12+
     #12#12#12#12#12#12#12#12#12#13#13#13#13#13#13#13+
     #13#13#13#13#13#13#13#13#13#13#13#13#13#13#14#14+
     #14#14#14#14#14#14#14#15#15#15#15#15#15#15#15#15+
     #15#15#16#16#16#16#16#16#17#17#19#25#0#6#6#7+
     #7#8#9#10#11#11#16#7#8#8#8#10#11#11#11#12+
     #14#14#15#15#6#6#7#7#7#7#7#7#7#7#7#8+
     #8#8#8#8#8#8#8#8#8#9#9#9#9#10#10#11+
     #11#11#11#11#11#11#12#12#12#12#12#12#12#12#12#12+
     #13#13#13#14#15#15#17#17#19#3#7#8#9#9#9#10+
     #11#11#12#13#15#16#24#0#0#5#6#6#6#7#7#8+
     #8#8#9#9#9#9#10#10#10#10#10#10#10#11#11#11+
     #11#11#11#11#12#12#12#12#12#12#14#14#15#15#16#17+
     #20#6#14#12#14#0#0#6#7#7#7#7#7#8#9#10+
     #10#11#12#12#13#13#14#15#15#25#5#7#7#8#9#9+
     #11#11#11#11#12#13#14#15#16#16#17#0#5#6#6#7+
     #7#7#7#7#7#7#7#7#7#7#8#8#8#8#8#8+
     #8#8#8#8#8#9#9#9#9#9#9#9#10#10#10#10+
     #10#10#10#10#11#11#11#11#11#11#11#11#12#12#12#12+
     #12#12#12#13#13#14#15#15#15#16#16#18#8#17#4#6+
     #7#7#7#7#9#9#10#10#10#11#11#11#11#11#11#12+
     #12#13#13#13#14#0#4#8#0#6#6#6#7#7#7#7+
     #7#7#7#7#7#7#7#7#8#8#8#8#8#8#8#8+
     #8#8#8#8#8#8#8#8#9#9#9#9#9#9#9#9+
     #9#9#9#9#9#9#9#9#9#9#10#10#10#10#10#10+
     #10#10#10#10#10#11#11#11#11#11#11#11#11#11#11#11+
     #11#11#11#11#12#12#12#12#12#12#12#12#12#12#12#12+
     #13#13#13#13#13#13#13#13#13#13#13#13#13#13#13#13+
     #13#14#14#14#14#14#14#14#14#14#14#14#14#14#14#15+
     #15#15#15#15#15#16#16#16#16#16#16#17#17#17#17#17+
     #19#19#19#20#20#21#24#0#5#8#8#9#10#12#13#14+
     #14#15#16#16#17#17#0#7#7#8#8#8#8#8#8#8+
     #9#9#10#10#10#10#10#10#11#11#11#11#12#12#12#12+
     #13#13#13#13#15#15#16#16#17#17#18#0#11#9#12#5+
     #9#10#10#12#14#15#21#8#8#9#11#12#22#0#6#6+
     #7#7#7#7#7#7#7#7#7#7#8#8#8#8#9#9+
     #9#9#9#9#9#10#10#10#10#10#10#10#10#11#11#11+
     #11#11#11#11#12#12#12#12#13#13#13#13#13#13#14#14+
     #14#14#14#14#14#15#16#16#17#17#20#5#9#7#8#12+
     #3#3#8#8#8#8#8#8#8#8#9#9#9#10#11#11+
     #11#11#12#12#13#13#13#14#14#15#19#20#0#6#6#6+
     #6#6#7#7#7#8#8#8#8#8#8#8#9#9#9#10+
     #10#10#11#11#11#11#11#11#11#11#11#11#11#12#12#12+
     #12#12#12#12#12#12#12#13#13#13#13#13#13#13#13#14+
     #14#14#14#14#15#15#15#16#16#16#16#19#3#15#3#8+
     #10#6#6#8#8#8#9#9#9#9#9#9#9#9#10#10+
     #10#10#10#10#10#10#10#11#12#12#12#12#12#12#12#12+
     #12#12#13#13#13#13#13#14#14#15#15#15#15#15#15#15+
     #16#17#17#17#18#20#19#13#13#14#7#7#7#7#7#8+
     #8#8#8#8#8#8#8#8#8#8#8#8#9#9#9#9+
     #9#9#9#9#9#9#9#9#9#9#9#9#9#9#9#10+
     #10#10#10#10#10#10#10#10#10#10#10#10#10#10#10#10+
     #10#10#11#11#11#11#11#11#11#12#12#12#12#12#12#12+
     #12#12#12#12#12#13#13#13#13#13#13#13#13#13#13#13+
     #13#13#13#13#13#13#13#13#14#14#14#14#14#14#14#14+
     #14#14#14#14#14#15#15#15#15#15#15#15#14#16#16#16+
     #16#16#16#16#16#16#16#16#17#17#17#17#18#13#14#8+
     #9#9#9#11#11#11#12#12#14#16#7#8#9#9#9#9+
     #9#9#9#9#9#10#10#10#10#11#12#12#12#12#13#15+
     #16#10#5#8#11#12#12#13#13#13#14#14#8#9#12#16+
     #16#17#4#6#6#7#8#8#8#8#8#8#8#9#9#9+
     #9#9#9#10#10#10#10#10#10#11#11#12#13#13#14#14+
     #16#18#18#20#21#9#9#9#9#10#10#10#10#11#11#11+
     #12#12#14#9#10#11#12#13#14#15#15#9#16#6#8#9+
     #11#11#12#12#12#13#14#10#11#12#14#17#10#10#12#12+
     #12#13#16#16#16#22#5#6#7#7#9#10#10#11#13#0+
     #11#13#12#13#15#9#15#6#7#7#7#8#8#8#8#8+
     #8#8#8#9#9#9#9#9#9#9#9#9#9#9#9#9+
     #10#10#10#10#10#10#10#10#10#11#11#11#11#11#11#12+
     #12#12#12#12#12#12#13#13#13#13#13#13#13#13#14#14+
     #14#15#15#16#17#17#17#17#17#16#7#11#12#13#13#16+
     #9#9#12#13#16#16#4#13#13#17#12#15#16#8#10#10+
     #10#11#11#13#14#7#8#8#8#9#9#9#9#9#10#10+
     #11#11#11#12#12#13#13#13#13#13#13#13#13#14#15#15+
     #15#15#16#16#16#18#21#30#0#11#13#16#8#8#9#11+
     #12#0#7#8#8#9#9#9#9#9#9#9#10#10#12#12+
     #13#14#16#21#7#7#9#10#10#10#10#10#10#11#13#13+
     #14#16#16#17#17#25#0#6#8#9#12#7#8#8#9#9+
     #9#9#9#9#9#10#10#10#10#10#10#10#10#10#10#11+
     #11#11#11#11#11#11#11#12#13#13#13#13#13#14#14#14+
     #14#14#15#15#15#16#16#17#17#18#19#18#21#11#12#17+
     #19#8#9#9#9#9#9#10#10#10#11#11#11#11#12#12+
     #12#12#13#13#13#13#14#14#14#14#15#15#16#16#16#17+
     #18#7#8#9#9#9#10#12#13#17#9#10#10#12#13#14+
     #14#16#17#17#10#16#23#0#6#6#7#7#7#8#8#8+
     #8#8#8#9#9#9#9#9#9#9#9#9#9#10#10#10+
     #10#10#10#10#10#10#10#10#10#10#10#10#10#10#10#10+
     #11#11#11#11#11#11#11#11#11#11#11#11#11#11#11#11+
     #11#11#11#11#11#11#11#11#11#11#12#12#12#12#12#12+
     #12#12#12#12#12#12#12#12#12#12#12#13#13#13#13#13+
     #13#13#13#13#13#13#13#14#14#14#14#14#14#14#14#14+
     #14#14#14#15#15#15#15#15#15#15#15#16#16#16#16#16+
     #16#16#16#17#17#17#17#17#17#17#17#17#17#18#18#18+
     #19#20#14#9#12#13#9#9#10#10#11#12#12#12#13#13+
     #15#15#16#17#18#22#9#11#12#13#17#10#11#7#7#8+
     #9#9#10#10#10#10#10#10#11#11#11#11#11#12#12#12+
     #12#12#12#13#13#13#13#13#14#14#14#14#14#15#15#16+
     #16#16#17#17#17#17#19#18#22#0#7#7#8#8#9#9+
     #10#10#10#10#10#10#10#10#11#11#12#12#12#12#12#12+
     #13#13#13#13#13#13#13#14#14#14#14#14#14#14#15#15+
     #15#15#16#16#16#16#16#16#16#16#17#18#18#18#18#21+
     #23#11#12#8#8#9#9#10#11#13#13#14#14#14#15#0+
     #8#9#9#9#9#10#11#11#11#11#12#12#12#12#13#13+
     #13#13#13#13#14#14#14#14#14#15#15#16#17#19#24#5+
     #9#11#12#9#6#9#10#11#12#13#14#15#15#16#16#22+
     #12#8#11#11#11#12#15#16#12#9#10#10#12#12#12#12+
     #13#15#15#16#16#16#18#20#21#0#10#7#8#9#9#9+
     #9#10#10#10#10#10#10#10#10#10#10#11#11#11#11#11+
     #11#11#11#11#11#11#12#12#12#12#12#12#12#12#12#12+
     #12#12#13#13#13#13#13#13#13#13#14#14#14#14#14#14+
     #14#14#14#14#14#14#14#14#15#15#15#15#15#15#15#15+
     #15#15#15#15#15#15#16#16#16#16#16#16#16#16#16#16+
     #17#17#17#17#17#17#17#17#17#17#17#18#18#18#18#19+
     #19#19#19#20#21#24#26#6#14#17#17#10#8#9#9#9+
     #10#10#10#10#10#11#11#11#11#11#11#11#11#11#11#11+
     #11#12#12#12#12#12#12#13#13#13#13#13#13#14#14#14+
     #14#14#14#14#14#14#14#14#14#15#15#15#15#16#16#16+
     #16#16#17#17#17#17#17#17#18#18#18#19#19#19#8#9+
     #11#12#10#10#9#9#9#10#10#10#10#11#11#11#11#12+
     #13#13#14#15#17#18#19#10#10#11#13#13#19#11#11#13+
     #15#15#16#9#10#10#11#11#12#12#13#14#14#14#15#15+
     #15#15#15#16#18#6#14#9#11#12#14#14#15#15#16#17+
     #6#12#14#14#17#25#11#19#9#12#13#13#23#11#15#10+
     #11#9#10#10#10#12#12#12#13#13#13#14#14#14#14#14+
     #15#15#16#16#16#17#17#18#19#19#19#20#20#21#7#16+
     #10#13#14#18#18#10#10#11#11#11#12#12#12#12#12#12+
     #12#12#13#13#13#13#13#13#13#14#14#15#15#15#15#15+
     #15#15#15#16#16#16#16#16#16#16#16#17#17#17#19#19+
     #19#19#19#20#21#22#22#23#24#7#12#13#13#17#17#11+
     #11#12#12#13#13#14#15#13#18#12#11#12#12#14#14#15+
     #16#16#19#19#20#22#10#13#13#13#14#14#15#15#17#8+
     #12#20#8#10#10#13#14#18#18#14#14#15#16#17#18#18+
     #21#24#12#12#13#13#13#13#13#13#13#13#14#14#14#14+
     #14#14#14#14#15#15#15#15#15#15#15#15#15#15#16#16+
     #16#16#16#16#16#16#16#16#16#16#17#17#17#17#17#17+
     #17#17#18#18#18#18#18#19#19#19#19#19#19#20#20#20+
     #21#14#14#15#15#16#18#18#18#19#19#13#13#14#14#14+
     #15#15#17#17#18#18#19#19#22#14#14#15#16#16#17#19+
     #12#15#18#22#22#10#13#14#15#15#16#16#16#18#19#20+
     #23#25#14#15#17#13#16#16#17#19#19#21#23#17#17#17+
     #18#18#19#20#20#20#20#21#17#18#20#23#23#16#17#23;

var
  no:integer;
  BiHua:integer;
  str:string; // str[40]
  BiHuaI:integer;
  ch1:char;
  ch2:char;
  len:integer;
begin
  str:=chnstr;
  BiHuaI:=1;
  BiHua:=0;
  len:=length(str);
  while BiHuaI<=len do
  begin
    ch1:=str[BiHuaI];
    BiHuaI:=BiHuaI+1;
    if (ord(ch1)>=176) and (BiHuaI<=len) then
    begin
      ch2:=str[BiHuaI];
      //BiHuaI:=BiHuaI+1;  ----这一行在只查一个汉字的时候用不着  2002.10
      no:=(ord(ch1)-176)*94+(ord(ch2)-160);
      BiHua:=ord(BiHuaTable[no]);
    end
    else
    begin
      BiHua:=0;
    end;
    break;  // 只要查出第一个汉字即可
  end;

  result:=BiHua;
end;
  
 
 2007-6-27 12:54:50    利用线程FTP上传上个目录指定的后缀文件
利用线程FTP上传上个目录指定的后缀文件
[轉]

function ftpup(mainpath:string;filename:string):Boolean;
var
  search:TSearchRec;
  ret:integer;
  tempfilenamestr:string;

begin
  ret:=findFirst(form1.source+'\'+filename,faanyfile,search);
  while ret=0 do
  begin
      if  ((search.attr and fadirectory)<> fadirectory) then
      begin
        if (search.name<>'.') or(search.name<>'..') then
        begin
          tempfilenamestr:=formatdatetime('yyyy',date)+formatdatetime('mm',date)+formatdatetime('dd',date)+formatdatetime('hh',time)+formatdatetime('mm',time)+formatdatetime('ss',time);
          if search.size<210000 then
          begin
            try
              form1.IdFTP1.Put(mainpath+'\'+search.Name,tempfilenamestr+copy(filename,2,4),true);
              form1.Memo1.Lines.Add('<img src="/pltp/'+tempfilenamestr+copy(filename,2,4)+'"><br><br>');
            except
              form1.Memo2.Lines.Add(search.Name+'文件异常!');
            end;
          end
          else
          begin
            form1.Memo2.Lines.Add(search.Name);
          end;
        end;
      end;
  ret:=FindNext(search);
  end;
  form1.IdFTP1.Free;
end;
function upftpthreadFun(P:pointer):Longint;stdcall;
var
  wb,wb1:string;
begin
  form1.Button1.Enabled:=false;
  form1.Memo1.Lines.Clear;
  form1.Memo2.Lines.Clear;
  wb1:=form1.ComboBox2.Text;//后缀名
  ftpup(form1.source,trim(wb1));
  form1.Memo1.Lines.SaveToFile(extractfilepath(paramstr(0))+'hnbxtx.text');
  form1.Memo1.Lines.Add('您所有图片上传成功!并己保存在'+extractfilepath(paramstr(0))+'hnbxtx.text中!请点击复制,将上面代码粘贴到步行天下论坛的发贴栏里。就可以成功发布您的图片了!');
  form1.Button1.Visible:=false;
  form1.Button3.Visible:=true;
end; 

 
 2007-6-27 13:09:38    在 Delphi 中使用原生 ADO 控制数据库
在 Delphi 中使用原生 ADO 控制数据库
[轉:http://www.delphibbs.com/delphibbs/DispQ.asp?LID=3047846 ]

我发现很多朋友在开发数据库时都使用 Delphi 自带的 ADO 组件 或 Diamond ADO,其实在 Delphi 中使用原生 ADO 接口也是十分方便和有效的。我使用原生 ADO 开发项目已有很长一段时间,也回答过一些朋友类似的问题,现在把自己的一点心得与大家分享,班门弄斧,只是希望能对大家有所帮助。当然,这帖子也是原生的,不是转贴的。

一、优点
1、大家知道 Delphi 对 ADO 接口进行了一番包装后形成了 ADOExpress,我想 Borland 的主要目的还是想与自己的数据敏感控件相连。然而事实上数据敏感控件并不是那么耀眼,如果你希望编出来的程序稍微有点水准的话就别用那玩意;如果你很少使用数据敏感控件,那么 ADOExpress 基本上失去了其应有的作用,无数冗余的属性、虚方法,不管你用不用得到一股脑给你编译进去,也会使你的程序再大上 200K;效率么,不说了。
2、MSDN 和 VB 中的例子你可以搬过来就用。
3、关于代码重用:我给大家的例子都是以函数或过程形式,重用性不好么?
4、别说帖子太长,那你看看 DB.pas, ADODB.pas 多长?

二、基本储备
1、一些必须的单元
uses
  Variants, ComObj;

2、一些基本常数(其它查 ADODB2000.pas 或搜索 adovbs.inc):
const
  adOpenDynamic = $00000002;
  adOpenStatic = $00000003;

  adLockOptimistic = $00000003;
  adLockBatchOptimistic = $00000004;

  adConnectUnspecified = $FFFFFFFF;
  adAsyncConnect = $00000010;

  adStateClosed = $00000000;
  adStateOpen = $00000001;
  adStateConnecting = $00000002;
  adStateExecuting = $00000004;
  adStateFetching = $00000008;

  adUseServer = $00000002;
  adUseClient = $00000003;

  adModeReadWrite = $00000003;

  adXactCursorStability = $00001000;

  adCmdText = $00000001;
  adCmdTable = $00000002;
  adCmdStoredProc = $00000004;
  adCmdFile = $00000100;

  adAffectCurrent = $00000001;
  adAffectGroup = $00000002;
  adAffectAll = $00000003;
  adAffectAllChapters = $00000004;

  adEmpty = $00000000; //空
  adInteger = $00000003; //长整
  adSingle = $00000004; //单精
  adDouble = $00000005; //双精
  adCurrency = $00000006; //货币
  adGUID = $00000048; //全球唯一的标志码
  adDate = $00000007; //日期
  adDBDate = $00000085; //日期值(yyyymmdd)
  adDBTime = $00000086; //时间值(hhmmss)
  adDBTimeStamp = $00000087; //日期时间值(yyyymmdd hhmmss)
  adBoolean = $0000000B; //布尔
  adVarChar = $000000C8; //字符串
  adVarWChar = $000000CA; //文本
  adLongVarWChar = $000000CB; //备注

//存储过程参数结构,只定义了常用的部分,如果需要自己加吧
type
  TParameter_ = record
    Name: WideString;
    Type_: LongWord;
    Direction: LongWord;
    Size: Longint;
    Value: OleVariant;
  end;

  TParameters_ = array of TParameter_;

3、一些基本函数和过程
//创建 Connection 对象
function CreateConnection: OleVariant;
//释放 Connection 对象;cnn 为 Connection 对象
procedure FreeConnection(var cnn: OleVariant);
//创建 Recordset 对象
function CreateRecordset: OleVariant;
//释放 Recordset 对象;rst 为 Recordset 对象
procedure FreeRecordset(var rst: OleVariant);
//创建 Command 对象
function CreateCommand: OleVariant;
//释放 Command 对象;cmd 为 Command 对象
procedure FreeCommand(var cmd: OleVariant);
//用 Connection 连接到 SQLServer 数据库;cnn 为 Connection 对象,srv 主机名或 IP 地址,uid 用户名,pwd 密码,db 数据库名
function ConnectToDB(cnn: OleVariant; const srv, uid, pwd, db: string): Boolean;
//执行 SQL 语句,有返回行,无事务处理;cnn 为 Connection 对象,rst 为 Recordset 对象,sql 为 SQL 语句(可以是存储过程)
function ExecSQL(cnn, rst: OleVariant; const sql: string): Boolean;
//执行 SQL 语句,无返回行,有事务处理;cnn 为 Connection 对象,cmd 为 Command 对象,sql 为 SQL 语句(可以是存储过程)
function ExecSQLA(cnn, cmd: OleVariant; const sql: string): Boolean;
//执行存储过程;cnn 为 Connection 对象,cmd 为 Command 对象,rst 为 Recordset 对象(用于接收来自存储过程的数据集);prc 为存储过程名; prms 为参数集合
function ExecProc(cnn, cmd, rst: OleVariant; const prc: string; prms: TParameters_): Boolean;

function CreateConnection: OleVariant;
begin
  try
    Result := CreateOleObject('ADODB.Connection');
    Result.CursorLocation := adUseServer;
    Result.IsolationLevel := adXactCursorStability;
    Result.Mode := adModeReadWrite;
    Result.Provider := 'SQLOLEDB.1';
  except
    if not VarIsEmpty(Result) then Result := Unassigned;
  end;
end;

procedure FreeConnection(var cnn: OleVariant);
begin
  if not VarIsEmpty(cnn) then
  begin
    if cnn.State <> adStateClosed then cnn.Close;
    cnn := Unassigned;
  end;
end;

function CreateRecordset: OleVariant;
begin
  try
    Result := CreateOleObject('ADODB.Recordset');
    Result.CacheSize := 1000;
    Result.CursorType := adOpenStatic;
    Result.CursorLocation := adUseServer;
    Result.LockType := adLockOptimistic;
  except
    if not VarIsEmpty(Result) then Result := Unassigned;
  end;
end;

procedure FreeRecordset(var rst: OleVariant);
begin
  FreeConnection(rst);
end;

function CreateCommand: OleVariant;
begin
  try
    Result := CreateOleObject('ADODB.Command');
    Result.CommandType := adCmdText;
    Result.CommandTimeout := 5;
  except
    if not VarIsEmpty(Result) then Result := Unassigned;
  end;
end;

procedure FreeCommand(var cmd: OleVariant);
begin
  if not VarIsEmpty(cmd) then cmd := Unassigned;
end;

function ConnectToDB(cnn: OleVariant; const srv, uid, pwd, db: string): Boolean;
begin
  Result := not VarIsEmpty(cnn);
  if Result then
  begin
    if cnn.State <> adStateClosed then cnn.Close;
    cnn.ConnectionString :=
      'Provider=SQLOLEDB.1;Persist Security Info=True;Initial Catalog=' +
      db + ';Data Source=' + srv + ';Connect Timeout=10;' +
      'Use Procedure for Prepare=1';
    try
      cnn.Open(cnn.ConnectionString, uid, pwd, adConnectUnspecified);
    except
      Result := False;
    end;
  end;
end;

function ExecSQL(cnn, rst: OleVariant; const sql: string): Boolean;
begin
  Result := not (VarIsEmpty(cnn) or VarIsEmpty(rst)) and (cnn.State = adStateOpen);
  if Result then
  begin
    if rst.State <> adStateClosed then rst.Close;
    try
      rst.Open(sql, cnn, adOpenStatic, adLockOptimistic, adCmdText);
    except
      Result := False;
    end;
  end;
end;

function ExecSQLA(cnn, cmd: OleVariant; const sql: string): Boolean;
begin
  Result := not (VarIsEmpty(cnn) or VarIsEmpty(cmd)) and (cnn.State = adStateOpen);
  if Result then
  begin
    cnn.BeginTrans;
    try
      cmd.ActiveConnection := cnn;
      cmd.CommandText := sql;
      cmd.Prepared := True;
      cmd.Execute;
      cnn.CommitTrans;
    except
      cnn.RollbackTrans;
      Result := False;
    end;
  end;
end;

function ExecProc(cnn, cmd, rst: OleVariant; const prc: string; prms: TParameters_): Boolean;
var
  i: Longint;
begin
  Result := not (VarIsEmpty(cnn) or VarIsEmpty(cmd)) and (cnn.State = adStateOpen);
  if Result then
  begin
    try
      cmd.CommandText := prc;
      cmd.CommandType := adCmdStoredProc;
      cmd.ActiveConnection := cnn;

      //之前,将我们自己的参数集合中的输入参数添入 Command 参数集合
      for i := Low(prms) to High(prms) do
        case prms[i].Direction of
          //未知类型的参数(adParamUnknown)既不算作输入参数也不算作输出参数
          adParamInput, adParamInputOutput:
            cmd.Parameters[prms[i].Name].Value := prms[i].Value;
        end;

      rst := cmd.Execute;

      //之后,将输出参数从 Command 参数集合读取到我们自己的参数集合
      for i := Low(prms) to High(prms) do
        case prms[i].Direction of
          //未知类型的参数(adParamUnknown)既不算作输入参数也不算作输出参数
          adParamOutput, adParamInputOutput:
            prms[i].Value := cmd.Parameters[prms[i].Name].Value;
          adParamReturnValue:
            prms[i].Value := cmd.Parameters[0].Value;
        end;
    except
      Result := False;
    end;
  end;
end;

三、访问数据
1、最前 rst.MoveFirst;
2、最后 rst.MoveLast;
3、向前 rst.MovePrevious;
4、向后 rst.MoveNext;
5、取当前记录 rst.Fields[0].Value 或 rst.Fields['字段名'].Value;
6、修改当前记录 rst.Update(rst.Fields[0].Name, 某值);
7、取消修改 rst.CancelUpdate;
8、删除当前记录 rst.Delete(adAffectCurrent);
9、删除所有记录 rst.Delete(adAffectAll);
10、追加记录
  rst.AddNew;
  rst.Fields[0].Value := 值1;
  rst.Fields[1].Value := 值2;
  rst.Update;
11、刷新 rst.Refresh;
12、记录数 rst.RecordCount
15、其它方法和属性查 MSDN 或 ADO 的帮助;

四、一些例子

//变量声明
var
  cnn, rst, cmd: OleVariant;

//创建对象
procedure TForm1.FormCreate(Sender: TObject);
begin
  cnn := CreateConnection;
  rst := CreateRecordset;
  cmd := CreateCommand;
end;

//释放对象
procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeCommand(cmd);
  FreeRecordset(rst);
  FreeConnection(cnn);
end;

//连接数据库
procedure TForm1.Button1Click(Sender: TObject);
begin
  if ConnectToDB(cnn, '127.0.0.1', 'sa', 'ok', 'Northwind') then
    Caption := '连接成功'
  else Caption := '连接失败';
end;

//取记录
procedure TForm1.Button2Click(Sender: TObject);
begin
  if ExecSQL(cnn, rst, 'SELECT * FROM Products') then
    Caption := VarToStr(rst.Fields['ProductName'].Value);
end;

//执行存储过程
(*
CREATE PROCEDURE GetProductName
    @ProductID int,
    @ProductName varchar(50) OUTPUT
AS
SELECT @ProductName = ProductName
FROM Products
WHERE ProductID = @ProductID
RETURN @ProductID
*)
procedure TForm1.Button3Click(Sender: TObject);
var
  prms: TParameters_;
begin
  SetLength(prms, 3);
  //参数 0 接收返回值;Name 取什么都行,但 Direction 必须标明为adParamReturnValue
  prms[0].Name := '@RETURN_VALUE';
  prms[0].Direction := adParamReturnValue;
  //参数 1 作为输入参数,Name 必须与实际参数名相同,Direction 标明 adParamInput
  prms[1].Name := '@ProductID';
  prms[1].Direction := adParamInput;
  prms[1].Value := 8;
  //参数 2 作为输出参数,Name 必须与实际参数名相同,Direction 标明 adParamOutput
  prms[2].Name := '@ProductName';
  prms[2].Direction := adParamOutput;
  //执行存储过程;如果不需要 Recordset 对象接收返回的数据集,就把它置空
  ExecProc(cnn, cmd, Null, 'GetProductName', prms);
  ShowMessage(prms[0].Value);
  ShowMessage(prms[2].Value);
end;

五、原生 ADO 与 Delphi ADOExpress 组件的对应关系
1、Connection <=> ADOConnection.ConnectionObject;
2、Recordset <=> ADODataSet.Recordset;
3、Command <=> ADOCommand.CommandObject;
4、? <=> ADOQuery,因为 ADOQuery 根本就不是原生 ADO 对象 
5、ExecSQL <=> ADODataSet.Open;
6、ExecSQLA <=> ADOCommand.Execute;
7、有了上面几个其它的就不多说了

六、与数据库结构有关的一些函数
1、动态改变字段名称
uses ComObj;
//Access
//TableName: 表名; OldColName: 原字段名; NewColName: 新字段名;
procedure RenameField(const TableName, OldColName, NewColName: string);
var
  cat, col: OleVariant;
begin
  cat := CreateOleObject('ADOX.Catalog');
  cat.ActiveConnection := ADOConnection1.ConnectionObject;
  col := CreateOleObject('ADOX.Column');
  col := DB.Tables[TableName].Columns[OldColName];
  col.Name := NewColName;
end;

//SQLServer
procedure RenameField(const TableName, OldColName, NewColName: string);
begin
  with ADOCommand1 do
  begin
    CommandText := 'EXEC sp_rename ''' + TableName + '.' + OldColName + 
      ''',''' + NewColName + ''',''COLUMN'';';
    Excute;
  end;
end;

2、取得 Access 库中的表结构
type
  TTableDef = record
    Name,
    DateCreated,
    LastUpdated,
    Description: string;
  end;

  TTableDefs = array of TTableDef;

procedure GetTableDefs(const DBName: string; out TableDefs: TTableDefs);
var
  dbEngine, db: OleVariant;
  i: Longint;
begin
  try
    dbEngine := CreateOleObject('DAO.DBEngine.36');
    db := dbEngine.OpenDatabase(DBName);
    SetLength(TableDefs, Longint(db.TableDefs.Count));
    for i := Low(TableDefs) to High(TableDefs) do
    begin
      TableDefs[i].Name := db.TableDefs[i].Name;
      TableDefs[i].DateCreated := db.TableDefs[i].DateCreated;
      TableDefs[i].LastUpdated := db.TableDefs[i].LastUpdated;
      try
        TableDefs[i].Description := db.TableDefs[i].Properties['Description'].Value;
      except
        TableDefs[i].Description := '';
      end;
    end;
  finally
    db := Unassigned;
    dbEngine := Unassigned;
  end;
end;

3、取得 Access 表中的字段结构
type
  TFieldDef = record
    Name: string;
    Types,
    Size: Longint;
    Description: string;
  end;

  TFieldDefs = array of TFieldDef;

procedure GetFieldDefs(const DBName, TableName: string; out FieldDefs: TFieldDefs);
var
  dbEngine, db: OleVariant;
  i: Longint;
begin
  try
    dbEngine := CreateOleObject('DAO.DBEngine.36');
    db := dbEngine.OpenDatabase(DBName);
    SetLength(FieldDefs, Longint(db.TableDefs[TableName].Fields.Count));
    for i := Low(FieldDefs) to High(FieldDefs) do
    begin
      FieldDefs[i].Name := db.TableDefs[TableName].Fields[i].Name;
      FieldDefs[i].Types := db.TableDefs[TableName].Fields[i].Type;
      FieldDefs[i].Size := db.TableDefs[TableName].Fields[i].Size;
      try
        FieldDefs[i].Description := db.TableDefs[TableName].Fields[i].Properties['Description'].Value;
      except
        FieldDefs[i].Description := '';
      end;
    end;
  finally
    db := Unassigned;
    dbEngine := Unassigned;
  end;
end;

4、不用 SQL 语句,仅用 ADOX,创建 Access 数据库、表、字段、字段备注(同样适用于 SQLServer)
function CreateMDB(const DBName, TableName: string): Boolean;
var
  cat, tbl, col: OleVariant;
begin
  Result := True;
  try
    try
      //生成数据库
      cat := CreateOleObject('ADOX.Catalog');
      cat.Create('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' + DBName);

      //生成表
      tbl := CreateOleObject('ADOX.Table');
      tbl.ParentCatalog := cat;
      tbl.Name := TableName;

      //生成一个带备注、自动编号的长整字段
      col := CreateOleObject('ADOX.Column');
      col.ParentCatalog := cat;
      col.Name := '带自动编号的长整字段';
      col.Type := adInteger;
      col.DefinedSize := 4;
      //自动编号字段就是长整字段,仅仅多了下面这句话
      col.Properties['Autoincrement'].Value := True;
      col.Properties['Description'].Value := '自动编号长整字段的说明';
      tbl.Columns.Append(col, adEmpty, 0);
      col := Unassigned;
      //生成一个带备注的文本字段
      col := CreateOleObject('ADOX.Column');
      col.ParentCatalog := cat;
      col.Name := '文本字段';
      col.Type := adVarWChar;
      col.DefinedSize := 50;
      col.Properties['Description'].Value := '文本字段的说明';
      tbl.Columns.Append(col, adEmpty, 0);
      //生成一个不带备注的双精字段,比上面要简单的多
      tbl.Columns.Append('双精字段', adDouble, 8);
      //生成一个不带备注的备注字段
      tbl.Columns.Append('备注字段', adLongVarWChar, 16);

      cat.Tables.Append(tbl);
    except
      Result := False;
    end;
  finally
    cat := Unassigned;
    tbl := Unassigned;
    col := Unassigned;
  end;
end;

七、进行分页显示数据
俺们几乎每天都见到网页用 ADO 进行分页(每次只取一定数量的记录),但是在 Delphi 中分页也成了稀罕的东西 :(
分页有三个常用的属性:PageSize—页面大小,PageCount—页面总数,AbsolutePage—决定跳转到哪一页面。
1、首先取得数据集,不罗嗦了
ADODataSet1.Open....
2、下面这个例子,将指定页面的数据读到 Memo1 中
procedure GetPageData(const nPage: Integer);
var
  i: Integer;
begin
  wiht ADODataSet1.Recordset do
  begin
    if (State = adStateClosed) or (nPage < 1) or (nPage > PageCount) then Exit;
    Memo1.Clear;
    AbsolutePage := nPage;
    //这里只能用 for 不能用 while(Eof 仍然表示数据集的结尾)
    for i := 1 to PageSize do
    begin
      Memo1.Lines.Add(Fields['ProductName'].Value);
      MoveNext;
      //防止因最后一页未满而产生越界
      if Eof then Exit;
    end;
  end;
end;

八、其它
1、希望此贴能对朋友们有所帮助,我写的这些都是经过实战检验的;
2、觉得有用的朋友可以试一下,如果觉得没用就当我没写,耽误你时间了。 
 
 2007-6-29 14:36:05    如何从INI文件读取CONNECTSTRING的值
如何从INI文件读取CONNECTSTRING的值
[轉載]

http://www.delphibbs.com/delphibbs/dispq.asp?lid=2559866

procedure TForm1.Button1Click(Sender: TObject);
  var
   MyInifile: TInifile;
   vstr, Filename : String;
begin
  Filename := ExtractFilePath(ParamStr(0))+'DB.ini';
   MyInifile :=TInifile.Create (Filename);  //和文件做关联
   EDIT1.Text := MyInifile.ReadString('Server ip','ip','');
end;

MyInifile.ReadString('Server ip','ip',''); 
frist parameter:  [] 符号的节点
second parameter:  = 号左边的
third parameter: = 号右的
fourthly parameter: 缺省或者为空。 

来自:crazyD, 时间:2004-4-15 8:36:30, ID:2559884
[red] ××××××××给你一个ini文件编程方面的文档×××××××××××××[/red]

INI文件在系统配置及应用程序参数设置与保存方面,具有很重要的作用,而且比起读写系统注册表来说,具有方便、安全
和“环保”等无可比拟的特点。所以现在几乎所有的可视化编程工具,如VB、VC、VFP、C++Builder和Delphi等都提供了读写
INI文件的方法。其中Delphi中操作INI文件,最为简洁,这是因为Delphi提供了一个TInifile类,从而无需调用系统的API函数,
使我们操作INI文件变得更加灵活和快捷。

首先,让我们先来了解一下INI文件的结构:
;注释
[小节名]
关键字=值
...
INI文件允许有多个小节(Section),每个小节又允许有多个关键字(Key), “=”后面是该关键字的值。值的类型有三种:字符串、整型
数值和布尔值。其中字符串存贮在INI文件中时不需要加引号,布尔值用0和1来表示,1表示“真”(True),0表示“假”(Fa
lse),注释则是以分号“;”作为一行的开头。

接着我们就来看一下具体在DELPHI5中,如何操作INI文件。首先要在程序中引用INI文件单元,方法是:在Interface的
Uses节增加IniFiles。接着再在变量定义部分增加一行:
MyInifile: TInifile;
然后,就可以对变量MyInifile进行创建、打开、读取、写入等操作了。
下面我们就分别来看一下如何进行以上所述的一系列操作:

1. 打开INI文件
MyInifile: =TInifile.Create ('LoginSys.ini');
上面这一行语句将会为变量MyInifile与具体的文件 LoginSys.ini建立联系,然后,就可以通过变量MyInifile,来读写
LoginSys.ini文件中的关键字的值了。值得注意的是,如果括号中的文件名没有指明路径的话,那么这个LoginSys.ini文件会
存储在Windows目录中。把LoginSys.ini文件存储在应用程序当前目录中的正确方法是:为其指定完整的路径及文件名。下面
的两条语句可以完成这个功能:
Filename: =ExtractFilePath(ParamStr(0))+'LoginSys.ini';
MyInifile:=TInifile.Create(Filename);

2. 读取关键字的值
针对INI文件支持的字符串型、整型、浮点型、日期型、日期时间型、时间型和布尔型七种数据类型,TIniFiles类提供了
七种不同的对象方法来读取INI文件中关键字的值。假设已定义变量vstr、vi、vf、vdt、vldt、vtime和vbln分别为字符串型、
整型、浮点型、日期型、日期时间型、时间型和布尔型类型,以下即为分别读取这七种类型关键字的示例代码:
vstr:=MyInifile.ReadString('小节名','关键字',缺省值);
vi:=Myinifile.ReadInteger('小节名','关键字',缺省值);
vf:=Myinifile.ReadFloat('小节名','关键字',缺省值);
vdt:=Myinifile.ReadDate('小节名','关键字',缺省值);
vldt:=Myinifile.ReadDateTime('小节名','关键字',缺省值);
vtime:=Myinifile.ReadTime('小节名','关键字',缺省值);
vbln:=MyInifile.ReadBool('小节名','关键字',缺省值);
其中缺省值为该INI文件不存在该关键字时返回的缺省值。

3. 写入INI文件
同样的,TInifile类也提供了七种不同的对象方法,向INI文件写入字符串型、整型、浮点型、日期型、日期时间型、时间
型和布尔型这七种类型的关键字。示例代码分别如下:
MyInifile.WriteString('小节名','关键字',变量或字符串值);
MyInifile.WriteInteger('小节名','关键字',变量或整型数值);
MyInifile.WriteFloat('小节名','关键字',变量或浮点型数值);
MyInifile.WriteDate('小节名','关键字',变量或短日期型数值);
MyInifile.WriteDateTime('小节名','关键字',变量或长日期型数值);
MyInifile.WriteTime('小节名','关键字',变量或时间型数值);
MyInifile.WriteBool('小节名','关键字',变量或True或False);
当这个INI文件不存在时,上面的语句还会自动创建该INI文件。而当一个小节不存在时,也会自动创建。

4. 删除关键字
如何不想再继续使用某个关键字的话,该怎么办呢?不用担心,在DELPHI中除了可用写入的方法为INI文件增加一个关键字之
外,TInifile类还提供了一个删除关键字的对象方法:MyInifile.DeleteKey('小节名','关键字');

5. 小节操作
增加一个小节可用写入一个关键字的方法来完成(DELPHI还未提供直接增加新小节的对象方法,其实也没多大必要的)。
删除一个小节可用下面的对象方法:
MyInifile.EraseSection('小节名');
另外TInifile类还提供了三种对象方法来对小节进行其它操作:
MyInifile. ReadSection('小节名',TStrings变量);可将指定小节中的所有关键字名读取至一个字符串列表变量中;
MyInifile.ReadSections(TStrings变量);可将INI文件中所有小节名读取至一个字符串列表变量中去。
MyInifile.ReadSectionValues('小节名',TStrings变量);可将INI文件中指定小节的所有行(包括关键字、=、值)读取至一
个字符串列表变量中去。
MyInifile.SectionExists('小节名');是一个布尔型函数,用来判断INI文件中是否存在这样一个小节。
6. 释放
INI文件类和其它运行时创建的类一样,也需要释放,不然同样会引起内存泄露。我们可以在程序中适当的位置(比如窗体
的Destroy事件中),用下面的语句释放MyInifile:
MyInifile.Destroy;

九、一个实例
下面用一个简单的例子(如图)演示了建立、读取、存贮INI文件的方法。LoginSys.ini文件中包含有“Settings”小节,和“Use
rName”(字符串)、“IfRegisted”(布尔值)和“OpenTimes”(整型值)三个关键字。程序在窗体建立读取这些数据,并
在窗体释放时更新LoginSys.ini文件。
附源程序清单
Unit Unit1;
Interface
Uses
Windows, SysUtils, Forms, IniFiles, Classes, Controls, StdCtrls, Buttons;
Type
TForm1 = class (TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Edit1: TEdit;
Edit2: TEdit;
chkBox1: TCheckBox;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
Procedure FormCreate(Sender: TObject);
Procedure FormDestroy(Sender: TObject);
Procedure chkBox1Click(Sender: TObject);
Procedure BitBtn1Click(Sender: TObject);
Procedure BitBtn2Click(Sender: TObject);
Private
{ Private declarations }
Public
{ Public declarations }
End;
Var
Form1: TForm1;
Implementation
Var
MyInifile: TInifile;
{$R *.DFM}

Procedure TForm1.FormCreate (Sender: TObject);
Var
Filename: string;
Begin
//把LoginSys.ini文件存储在应用程序当前目录中
Filename:= ExtractFilePath(paramstr(0))+'LoginSys.ini';
MyInifile:= TInifile.Create(filename);
Edit1.Text:= MyInifile.readstring('Settings','UserName','党博昌');
Edit2.text:= inttostr(1+MyInifile.readinteger('Settings','OpenTimes',0));
chkBox1.Checked:= MyInifile.readbool('Settings','ifRegisted',False);
chkBox1Click(Sender);
End;

Procedure TForm1.FormDestroy(Sender: TObject);
Begin
MyInifile.WriteString ('Settings','UserName', Edit1.Text);
MyInifile.WriteInteger ('Settings','OpenTimes',strtoint(Edit2.text));
MyInifile.WriteBool ('Settings','ifRegisted', chkBox1.Checked);
MyInifile.Destroy;
End;

Procedure TForm1.chkBox1Click(Sender: TObject);
Begin
if ChkBox1.Checked =True then ChkBox1.Caption :='是'
else if ChkBox1.Checked =False then ChkBox1.Caption :='否';
End;

Procedure TForm1.BitBtn1Click(Sender: TObject);
Begin
//在此添加判断是否为已注册用户的语句,及其它代码';
End;
Procedure TForm1.BitBtn2Click(Sender: TObject);
Begin
Form1.DoDestroy;
End;

End.
  


来自:crazyD, 时间:2004-4-15 8:38:10, ID:2559891
1、Delphi中拷贝文件的几种方法

  {方法一:用File stream }
  Procedure FileCopy( Const sourcefilename, targetfilename: String );
  Var
  S, T: TFileStream;
  Begin
  S := TFileStream.Create( sourcefilename, fmOpenRead );
  try
  T := TFileStream.Create( targetfilename,fmOpenWrite or fmCreate );
  try
  T.CopyFrom(S, S.Size ) ;
  finally
  T.Free;
  end;
  finally
  S.Free;
  end;
  End;

  { 方法二:使用内存块进行读写 }

  procedure FileCopy(const FromFile, ToFile: string);
  var
  FromF, ToF: file;
  NumRead, NumWritten: Word;
  Buf: array[1..2048] of Char;
  begin
  AssignFile(FromF, FromFile);
  Reset(FromF, 1); 
  AssignFile(ToF, ToFile);
  Rewrite(ToF, 1); 
  repeat
  BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
  BlockWrite(ToF, Buf, NumRead, NumWritten);
  until (NumRead = 0) or (NumWritten < >  NumRead); 
  CloseFile(FromF);
  CloseFile(ToF);
  end;

  2、控制INI文件

  要利用.INI文件做程序有关数据的存储工作,就需要能读和写.INI文件,所以列了如下方法给大家参考:

  {方法一:用 Windows API 函数}

  ① 从.INI文件中获取字符串
  var
  strResult:array[0..30] of Char;
  begin
  GetPrivateProfileString(' desktop ', 'wallpaper', 
  'c:\windows\newwall.bmp' , strResult, 100, 
  'c:\windows\win.ini' );
  edit1.text:=strResult; //显示取得字符串
  end;
  ② 从.INI文件中获取整数
  var
  nResult: integer;
  begin
  nResult := GetPrivateProfileString(' desktop ', ' tilewallpaper', 
  0 , 'c:\windows\win.ini' );
  edit1.text:=intostr(nResult); //显示取得整数
  end;
  ③ 向.INI文件写入字符串
  WritePrivateProfileString('desktop', 'wallpaper',
  strWrite ,'c:\windows\win.ini');
  { 方法二:使用TiniFile进行读写 }
  ① 从.INI文件中读字符串
  var MyIni: TIniFile;
  begin
  MyIni := TIniFile.Create('c:\windows\win.ini');
  edit1.text:=MyIni.ReadString('Desktop', 'Wallpaper', '');
  end;
  ② 向.INI文件中写入字符串
  var MyIni: TIniFile;
  begin
  MyIni := TIniFile.Create('c:\windows\win.ini');
  MyIni.WriteString('desktop', 'wallpaper', 'c:\a.bmp');
  end;

  3、用Delphi实现将纯文本资料转入数据库 

  在我们日常工作中,常会碰到这样一个难题:一大堆收集好的纯文本格式,比较规整的资料怎样才能将它们分离,转到自己已经建好的数据库中进行管理呢?例如,有一段人事档案资料document.txt,内容如下:

  张强,25,助理工程师,

  王宏,30,工程师,

  李远,45,高级工程师,

  要将它转入数据库中,document.db结构如下:

  姓名,年龄,职称

  怎么办呢?现在通过使用delphi编程,很好地解决了这个难题。Delphi提供了许多功能强大,丰富的字符处理函数和过程,常用的有:

  ① function Length(S:String):Integer  //返回串的长度

  ② function Copy(S:String; Index,Count: Integer):String

  //给出一个字符串中串的拷贝

  ③ function Pos(Substr:String; S:String); Integer  

  //查找子串在字符串中的位置

  ④ Procedure Delete(Var S:String; Index,Count: Integer);

  //从一个字符串中去除子串

  利用Delphi提供的已有函数和过程基础上编制自己的三个函数,实现了纯文本格式资料转入数据库功能。只要Delphi支持的数据库都可以支持。

  Document.txt中每行数据为一个字符串,字符串中每个被分割的数据为一个字段,分割每个字段的字符为分割符,这里是逗号,也可以是、;#等符号。具体思想是:先将字符串进行调整,然后把串中每个字符同分割符比较,将不是分割符的字符追加到MyStr串中,最后得到一个字段的内容。通过一个循环,就可以将一个字符串分成几个字段。

  Function GetSubStr(var aString:string; SepChar:String): String;

  //得到字符串中一个子串

  因要改变参数aString的值,所以将它用var定义。

  Function GetSubStrNum(aString, SepChar: String): Integer;

  //计算一个字符串要被分割成几个字段。

  参数:aString是所需分割的一个字符串,

  SepChar是分割符。
  Function GetSubStrNum(aString:String;SepChar:String):integer;
  var
  i:Integer;
  StrLen:Integer;
  Num:Integer;
  begin
  StrLen:=Length(aString);
  Num:=0;
  For i:=1 to StrLen do
  If Copy(aString,i,1) = SepChar then
  Num:=Num+1;
  result:=Num;
  end;
  Function GetSubStr(var aString:String;SepChar:String):String;
  var
  Mystr:String;
  StrLen:Integer;
  SepCharPos:Integer;
  begin
  StrLen:=Length(aString);
  SepCharPos:=Pos(SepChar,aString); //计算分割符在子串中的位置
  MyStr:=Copy(aString,1,SepCharPos-1); //将分割符前所有字符放到mystr串中
  Delete(aString,1,SepCharPos); //除去分割符和分割符前的子串
  GetSubStr:=MyStr; //返回一个字段
  end;

  有了上面三个函数,现在介绍一下具体的应用:

  ① 首先建立一个窗体Forml,加入一个RichEditl(或Menol),一个按钮Buttonl和一个Tablel,设置Tablel的属性:

  Tablell.DataBaseName:= 'c:\test';

  Tablell.TableName:= 'document.db';

  ② 分别加入以下程序:

  const
  SepChar=',' ;
  procedure TForm1.FormCreate(Sender: TObject);
  begin
  RichEdit1.Lines.LoadFromFile('c:\test\test.txt');
  end;
  procedure TForm1.Button1Click(Sender: TObject);
  var
  i,j,num:Integer;
  MyLine:String;
  item:array[1..3] of string;
  begin
  For i:=0 to RichEdit1.Lines.Count-1 do
  begin
  MyLine:=Richedit1.Lines[i];
  num:=GetSubStrNum(myline,SepChar);
  for j:=1 to num do
  item[j]:=GetSubStr(myline,SepChar);
  table1.open;
  with table1 do
  begin
  table1.insert;
  table1name.Asstring:=item[1];
  table1age.Asinteger:=strtoint(item[2]);
  table1title.Asstring:=item[3];
  table1.post;
  end;
  table1.close;
  end;
  end;
  


来自:多情剑客无情剑, 时间:2004-4-15 8:39:19, ID:2559894
var
  Str:String;
  MyList:TStringlist;
begin
  AdoConnection1.Close;
  if FileExists(ExtractFilePath(Application.ExeName)+'MyConfig.ini') then
    begin
      MyList:=TStringList.Create;
      MyList.LoadFromFile(ExtractFilePath(Application.ExeName)+'MyConfig.ini');
      Str:=MyList.Text;
      FreeAndNil(MyList);
      AdoConnection1.ConnectionString:=Str;
    end else
    begin
      Str:=ExtractFilePath(Application.ExeName)+'\data\zyjs.mdb';
      if FileExists(Str) then
      begin
        AdoConnection1.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;'+
          'Data Source='+Str+';Persist Security Info=False;';
      end
      else //EditConnectionString(AdoConnection1);
        AdoConnection1.ConnectionString:= PromptDataSource(Application.Handle ,
          AdoConnection1.ConnectionString);  //
    end;
   AdoConnection1.open;
  


来自:app2001, 时间:2004-4-15 8:44:01, ID:2559902
procedure TDataModule1.DataModuleCreate(Sender: TObject);
var
  ini: TIniFile;
  ServerName, S,S1: string;
  UserName, PWD: string;
  DatabaseName1,SqlqryMode1,HostName1:string;
begin
  S := ExtractFilePath(Application.ExeName);
  if S[Length(S)] <> '\' then
    S := S +'\' +'LMD.ini'
  else
    S := S +'lmd.ini';
  ini := TIniFile.Create(S);
  //  readregedit(username,pwd);//读取注册表取用户和密码
  try
    UserName := ini.ReadString('Database', 'UserName', 'sa');
    Pwd := ini.ReadString('Database', 'Password', '');
    ServerName := ini.ReadString('Database', 'ServerName', 'server1');
    DatabaseName1:=ini.ReadString('Database','DatabaseName','LD');
    HostName1:=ini.ReadString('Database','HostName',' ');
  finally
    ini.Free;
  end;
  ADOConnection1.Connected := false;
  try
    S1:='Provider=SQLOLEDB.1;'+
    'Password='+PWD+';'+
    'Persist Security Info=False;'+
    'User ID='+UserName+';'+
    'Initial Catalog='+DatabaseName1+';'+
    'Data Source='+ServerName+';'+
    'Use Procedure for Prepare=1;'+
    'Auto Translate=True;'+
    'Packet Size=4096;'+
    'Workstation ID='+HostName1+';'+
    'Use Encryption for Data=False;'+
    'Tag with column collation when possible=False';
    ADOConnection1.ConnectionString:=S1;
    ADOConnection1.Connected := true;
  except
    Application.MessageBox('连接数据库服务器失败,程序异常终止,请检查局域网络通讯是否畅通!',
      '错误框', mb_Ok + mb_IconStop);
    Application.Terminate;
  end;
end;
  


来自:jwfy2001, 时间:2004-4-15 8:45:55, ID:2559907
我想得到具体的从INI中读取到CONNECTSTRING的例子  


来自:yplusplus, 时间:2004-4-15 8:46:37, ID:2559909
关键是ini文件操作的几个函数  


来自:蓝色幻想, 时间:2004-4-15 9:23:02, ID:2560019
建立一個連接信息類
  TDBConnectionInfo = class( TObject )
  private
    FHostName : String ;
    FDataBaseName : String ;
    FLogname : String ;
    FPassWord : String ;
    FConnStr : String ;
    procedure SetConnStr(const Value: String);
  public
    Property  HostName : String      Read  FHostName  Write FHostName ;
    Property  DataBaseName : String  Read  FDataBaseName Write FDataBaseName ;
    Property  LogName : String       Read  FLogName Write FLogName ;
    Property  PassWord  : String     Read  FPassWord Write FPassWord ;
    Property  ConnStr : String read FConnStr write SetConnStr ;
  end;

procedure TDBConnectionInfo.SetConnStr(const Value: String);
begin
  FConnStr := 'Provider=SQLOLEDB.1;Password='+ FPassWord +
                              ';Persist Security Info=True;User ID='+ FLogName +
                              ';Initial Catalog='+  FDataBaseName +
                              ';Data Source='+ FHostName ;
end;

procedure TDM.DataModuleCreate(Sender: TObject);
var
  filepath:string;
begin
   filepath:=ExtractFilePath(Paramstr(0));
   if copy(filepath,length(filepath),1)<>'\' then
      filepath:=filepath+'\' ;
   TmpIni:=Tinifile.Create(filepath+'config.ini');
   UserInfo.AppPath := FilePath ;  { TODO : 設置應用程序Path }
   { TODO : 讀取服務信息 }
   DBConn.HostName := tmpini.ReadString('Server Info','server','192.168.1.53');
   DBConn.DataBaseName := tmpini.ReadString('Server Info','database','attdata');
   DBConn.LogName :=  tmpini.ReadString('Server Info','username','sa');
   DBConn.PassWord := tmpini.ReadString('Server Info','password','');
   DBConn.ConnStr := '' ;
   tmpini.Free ;
   try
     adoconn.Connected:=false;
     adoconn.ConnectionString:= DBConn.ConnStr ;
     adoconn.Connected:=true;
   except
        Application.MessageBox('提示','不能連接到服務器',MB_OK+MB_ICONERROR);
        Application.Terminate;
   end;  


来自:蓝色幻想, 时间:2004-4-15 9:24:17, ID:2560030
ini文件內容如下
服務信息
[Server Info]
Server=192.168.1.53
DataBase=attdata
UserName=sa
PassWord=  


来自:ahjie, 时间:2004-4-15 9:28:01, ID:2560044
ini这样的话
可以在程序里面先定义一个Connectionstring的模板啊
然后取得Server , DataBase UserName,PassWord后,把Connectionstring format一下
就是需要的Connectionstring了
ini的读写,上面的兄弟们已经介绍的很清楚了  


来自:huangseng, 时间:2004-4-15 9:56:18, ID:2560131
为什么不用注册表来读写connectstring
比ini方便得多  


来自:gyh75, 时间:2004-4-15 10:01:38, ID:2560146
INI文件中:
[ADO]
Provider=SQLOLEDB.1
Password=
Persist Security Info=True
User ID=sa
In