2009年5月30日
Delphi TJclAnsiRegEx
和 Perl-compatible Regular Ex-pressions
將 \Program Files\GnuWin32\bin\pcre3.dll 複製到
\WINDOWS\system32 目錄下,並更名為 pcre.dll
>copy "\Program Files\GnuWin32\bin\pcre3.dll" \WINDOWS\system32\pcre.dll
開啟 Delphi 在 Form Create 事件中加入
uses
JclPCRE;
procedure TForm1.FormCreate(Sender: TObject);
var
Re: TJclAnsiRegEx;
s: string;
i: Integer;
begin
Memo1.Lines.Clear;
Re := TJclAnsiRegEx.CReate;
try
Re.Compile('\d+', True, False);
s := 'hello 1234 test 5678 number'#13#10'90';
i := 1;
while Re.Match(s, i) do
begin
Memo1.Lines.Add(Re.CaptuRes[0]);
i := Re.CaptureRanges[0].LastPos +2;
end;
finally
Re.FRee;
end;
end;
{
1234
5678
90
}
網頁或郵件放入 Skype button
1. Enter your Skype Name 填入你的 Skype 帳號
…
4. Copy & paste this code
選擇用 Web HTML 或 Email HTML
copy 下來 paste 到 Web 或 Email 中
中文網址
http://www.skype.com/intl/zh-Hant/share/buttons/
Regular expression 規則運算式(正規表示)
http://irw.ncit.edu.tw/peterju/webslide/re/
http://www.regular-expressions.info/
http://phi.sinica.edu.tw/aspac/reports/94/94019/
http://www.javaworld.com.tw/jute/post/view?bid=20&id=130126
http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html
Perl-compatible Regular Ex-pressions
Windows 版 http://gnuwin32.sourceforge.net/
安裝 Pcre for Windows 後,可以找到程式
C:\Program Files\GnuWin32\bin\pcregrep.exe
可將 C:\Program Files\GnuWin32\bin 加入環境變數 path 中
使用 pcregrep
Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]
例如要例出 a.txt 中有含數字的每一行
>pcregrep \d+ a.txt
Delphi JEDI CreateJunctionPoint (SymbolicLink)
uses
SysUtils, JclNTFS;
begin
// function NtfsCreateJunctionPoint(const Source, Destination: string): Boolean;
// Source must empty directory
NtfsCreateJunctionPoint('c:\tmp\ProgramFiles', 'C:\Program Files');
// Delete
// NtfsDeleteJunctionPoint('c:\tmp\ProgramFiles');
end.
Delphi JEDI CreateHardLink
uses
SysUtils, JclNTFS;
begin
NtfsCreateHardLink('C:\LINK_ODBC.INI', 'C:\WINDOWS\ODBC.INI');
end.
Delphi JEDI JvSearchFiles
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
procedure FindFile(Sender: TObject; const AName: String);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
JvSearchFiles;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
with TJvSearchFiles.Create(nil) do
begin
Files.Clear;
Directories.Clear;
DirOption := doIncludeSubDirs;
Options := Options + [soOwnerData];
FileParams.FileMasks.Text := '*.PAS';
FileParams.SearchTypes := [stFileMask];
RootDirectory := 'C:\JVCL333';
OnFindFile := FindFile;
Search;
Free;
end;
end;
procedure TForm1.FindFile(Sender: TObject;
const AName: String);
begin
Memo1.Lines.Add(AName);
end;
Delphi JEDI ScreenShot 擷取螢幕畫面到剪貼簿
// 在 Form 上放入一個 Button 並加入 onclick 事件
uses
JclGraphics, Clipbrd;
procedure TForm1.Button1Click(Sender: TObject);
var
Bitmap: TBitmap;
AFormat: Word;
AData: THandle;
APalette: HPALETTE;
begin
Bitmap := TBitmap.Create;
try
// Left, Top, Width, Height, HWND_DESKTOP
ScreenShot(Bitmap, 0,0, 300, 200, HWND_DESKTOP);
Bitmap.SaveToClipboardFormat(AFormat, AData, APalette);
ClipBoard.SetAsHandle(AFormat, AData);
finally
Bitmap.Free;
end;
end;
Delphi JEDI Form CaptionButton
// ...
// 在 uses 中加入 JvCaptionButton
uses
... , JvCaptionButton;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
// 加入 TJvCaptionButton 和 bonclick TNotifyEvent
b: TJvCaptionButton;
procedure bonclick(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.bonclick(Sender: TObject);
begin
ShowMessage('Hello');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
B := TJvCaptionButton.Create(self);
B.Caption := 'A';
B.onclick := bonclick;
end;
// ...
執行程式後 Caption 上就會多一個 'A' Button 了
Delphi JEDI TrayIcon Application
加入元件
Jv Non-Visual -> JvTrayIcon
Standard -> PopupMenu
PopupMenu1 add MenuItem
設定元件屬性
MenuItem.Caption = Show
MenuItem.Name = Show1
JvTrayIcon1.Active = True
JvTrayIcon1.PopupMenu = PopupMenu1
// 加入 Show1 onclick 事件
procedure TForm1.Show1Click(Sender: TObject);
begin
JvTrayIcon1.ShowApplication;
end;
// 加入 Form1 OnCreate 事件
procedure TForm1.FormCreate(Sender: TObject);
begin
JvTrayIcon1.HideApplication;
end;
執行程式後會直接隱藏到 TrayIcon 中
右鍵點 PopupMenu -> Show 還原視窗
Delphi JEDI JvDebugHandler 紀錄 Exception 資訊 (full stack trace)
需先安裝 JEDI VCL for Delphi
先開啟 Map file
Project -> Options -> Linker -> Map file 選擇 Detailed 按 OK
放入元件 Jv System -> JvDebugHandler
放入元件 Memo
加入 Form1 OnCreate 事件
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
try
Format('%s', [3]);
except
end;
end;
加入 JvDebugHandler1 OnOtherDestination 事件
procedure TForm1.JvDebugHandler1OtherDestination(Sender: TObject);
begin
Memo1.Lines.AddStrings(JvDebugHandler1.ExceptionStringList);
end;
執行程式並跳過 Exception
{ Memo
2008/3/29 下午 12:16:05 Exception EConvertError occured in ConvertErrorFmt at 0 in file
Message: Format '%s' invalid or incompatible with argument
Call stack:
[00408041] SysUtils.ConvertErrorFmt
[00409467] SysUtils.FmtStr
[00409412] SysUtils.Format
[0045EC2B] Unit1.TForm1.FormCreate (Line 32, "Unit1.pas")
[004470E1] Forms.TCustomForm.DoCreate
[00446DC1] Forms.TCustomForm.AfterConstruction
[0044E481] Forms.TApplication.CreateForm
[0045EFEF] Project1.Project1 (Line 11, "C:\Delphi7\Projects\Project1.dpr")
預設 JvDebugHandler.LogToFile = True
也會輸出 log file,預設檔名為 ${Application.Title} ERRORLOG.txt
可以直接設定 JvDebugHandler.LogFileName 來指定 log file 檔名
Delphi JEDI Persistence Form
Add Components
Jv Persistence -> JvAppIniFileStorage
Jv Persistence -> JvFormStorage
Jv Dialogs -> JvTipOfDay
Edit Object properties
JvFormStorage1.AppStorage = JvAppIniFileStorage1
JvAppIniFileStorage1.FileName = 'APP1.INI'
JvTipOfDay1.AppStoragePath = 'TIP'
JvTipOfDay1.Options = [toShowonstartUp, toUseAppStorage]
JvTipOfDay1.AppStorage = JvAppIniFileStorage1
JvTipOfDay1.Tips.Strings = (
'Tips 1'
'Tips 2'
'Tips 3')
Run program show Tips
Exit program save APP.INI file
Re-run program read APP.INI file and change properties
Delphi JEDI TJvComputerInfoEx 取得系統資訊
需先安裝 JEDI VCL for Delphi
uses
JvComputerInfoEx;
procedure TForm1.FormCreate(Sender: TObject);
var
JvComputerInfoEx1: TJvComputerInfoEx;
begin
JvComputerInfoEx1 := TJvComputerInfoEx.Create(Self);
with JvComputerInfoEx1, Memo1.Lines do
begin
Clear;
Values['OS Name'] := OS.ProductName +' '+ OS.VersionCSDString;
Values['CPU'] := CPU.Name;
Values['Screen'] := Format('%d X %d', [Screen.Width, Screen.Height]);
Values['Battery'] := Format('%d%%', [APM.BatteryLifePercent]);
Values['Desktop'] := Folders.Desktop;
Values['IPAddress'] := Identification.IPAddress;
Values['DomainName'] := Identification.DomainName;
end;
JvComputerInfoEx1.Free;
end;
{ Memo1
OS Name=Microsoft Windows XP Service Pack 2
CPU=Intel(R) Core(TM)2 Duo CPU T7300 @ 2.00GHz
Screen=1280 X 800
Battery=79%
Desktop=C:\Documents and Settings\Administrator\桌面
IPAddress=169.254.254.234
DomainName=SOLNONE
}
Delphi JEDI 增加、刪除 Windows 使用者帳號
需先安裝 JEDI VCL for Delphi
建立 Delphi Console Application
File -> New -> Other... -> Console Application
輸入參數
Run -> Paramters...
Paramters 中輸入 Username Password
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, JclLANMan, System;
var
Username: string;
Password: string;
Input: string;
begin
if ParamCount < 2 then
begin
WriteLn(ExtractFileName(ParamStr(0)) + ' Username Password');
ReadLn(Input);
Exit;
end;
Username := ParamStr(1);
Password := ParamStr(2);
if CreateLocalAccount(Username, 'FullName',
Password, 'Comment', 'HomeDir', 'Script') then
begin
WriteLn('Create User ' + Username + ' Success');
if DeleteLocalAccount(Username) then
begin
WriteLn('Delete User ' + Username + ' Success');
end
else
begin
WriteLn('Delete User ' + Username + ' Success');
end;
end
else
begin
WriteLn('Create User ' + Username + ' Failure');
end;
ReadLn(Input);
end.
{ Stdout
Create User Username Success
Delete User Username Success
}
Delphi JEDI MultiStringHolder 存多個 TStrings
需先安裝 JEDI VCL for Delphi
在 Form 中
放入 TMemo 顯示訊息
放入 Jv Non-Visual -> TJvMultiStringHolder
加入 Form1 OnCreate 事件
procedure TForm1.FormCreate(Sender: TObject);
begin
// Add config
with JvMultiStringHolder1.MultipleStrings.Add do
begin
Name := 'config';
with Strings do
begin
Values['Server'] := 'localhost';
Values['User'] := 'Solnone';
Values['Access'] := 'ReadOnly';
end;
end;
// Add users
with JvMultiStringHolder1.MultipleStrings.Add do
begin
Name := 'users';
with Strings do
begin
Add('Solnone');
Add('May');
Add('John');
end;
end;
// Show
with JvMultiStringHolder1 do
begin
Memo1.Lines := ItemByName['config'].Strings;
Memo1.Lines.Add('------');
Memo1.Lines.AddStrings(ItemByName['users'].Strings);
end;
end;
{ Memo1
Server=localhost
User=Solnone
Access=ReadOnly
------
Solnone
May
John
}
Delphi JEDI CreateProcess 執行 Console 程式
需先安裝 JEDI VCL for Delphi
在 Form 上
放入 Jv Non-Visual -> TJvCreateProcess
放入 TEdit, TButton 來執行 CommandLine
放入 TMemo 來顯示 Console 訊息
放入 TActionManager 來建立一個 Action
在 ActionManager1 雙擊滑鼠左鍵開啟 Editing ActionManager
新增一個 New Action [Inc]
加入 Action1 OnExecute 事件
procedure TForm1.Action1Execute(Sender: TObject);
var
cmd: String;
path: String;
begin
with JvCreateProcess1 do
begin
case State of
psReady: begin
cmd := Edit1.Text;
commandLine := cmd;
path := ExtractFilePath(cmd);
CurrentDirectory := path;
Memo1.Clear;
Run;
end;
psRunning,
psWaiting: begin
JvCreateProcess1.CloseApplication;
end;
end;
end;
end;
加入 Action1 OnUpdate 事件
procedure TForm1.Action1Update(Sender: TObject);
begin
with JvCreateProcess1 do
begin
case State of
psReady: Button1.Caption := 'Run';
psRunning, psWaiting: Button1.Caption := 'Close';
end;
end;
end;
加入 JvCreateProcess1 OnRead 事件
procedure TForm1.JvCreateProcess1Read(Sender: TObject; const S: String;
const StartsOnNewLine: Boolean);
begin
Memo1.Lines.Add(S);
end;
修改屬性
Button1.Action = Action1
Edit1.Text = 'netstat -na'
JvCreateProcess1.StartupInfo.ShowWindow = swHide
JvCreateProcess1.StartupInfo.DefaultWindowState = False
JvCreateProcess1.ConsoleOptions = [coOwnerData, coRedirect]
Memo1.ScrollBars = ssBoth
Memo1.WordWrap = False
執行程式, 按下 Run Button, Memo1 會取得到 stdout
Active Connections
Proto Local Address Foreign Address State
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING
TCP ...
Delphi JEDI 取得 Windows Service Description
uses
JclSvcCtrl;
在 Form 中放入 TMemo 顯示訊息
加入 Form1 OnCreate 事件
procedure TForm1.FormCreate(Sender: TObject);
var
SCManager: TJclSCManager;
I: Integer;
Service: TJclNtService;
begin
Memo1.Clear;
Memo1.WordWrap := False;
Memo1.ScrollBars := ssBoth;
SCManager := TJclSCManager.Create;
try
SCManager.Refresh(True);
for I := 0 to SCManager.ServiceCount -1 do
begin
Service := SCManager.Services[I];
Memo1.Lines.Values[Service.ServiceName] := Service.Description;
end;
finally
SCManager.Free;
end;
end;
{
AFD=AFD 網路支援環境
alerter=通知選取的使用者及電腦系統管理警示。...
ALG=提供網際網路連線共用和 Windows 防火牆的第三...
...
}
Delphi JEDI SingleInstance (單一執行程式)
在 Menu 中選 View -> Units... [Ctrl + F12]
選擇 Project1
uses JclAppInst
加入 JclAppInstances.CheckSingleInstance;
Project1 內容如下
program Project1;
uses
JclAppInst,
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
JclAppInstances.CheckSingleInstance;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
編譯,執行多次程式 Project1.exe
就只會有一個實體程式在執行中
Delphi JEDI Mouse Gesture 滑鼠手勢
需先安裝 JEDI VCL for Delphi
在 Form 中
放入 TMemo 顯示訊息
放入 Jv Non-Visual -> TJvMouseGestureHook
加入 JvMouseGestureHook1.OnouseGestureCustomInterpretation 事件
procedure TForm1.JvMouseGestureHook1MouseGestureCustomInterpretation(
Sender: TObject; const AGesture: String);
begin
Memo1.Lines.Add(AGesture);
end;
加入 Form1 OnCreate 事件
procedure TForm1.FormCreate(Sender: TObject);
begin
JvMouseGestureHook1.Active := True;
end;
執行程式,即可用滑鼠右鍵拖曳畫出方向
上 U
下 D
左 L
右 R
左下 1
右下 3
左上 7
右上 9
Delphi JEDI TJvLogFile
需先安裝 JEDI VCL for Delphi
在 Form 中
放入 Jv Non-Visual -> TJvLogFile
FileName = 'c:\log.txt'
AutoSave = True
SizeLimit = 1048576 //1M
放入 TTimer 元件,並加入 Timer1 OnTimer 事件
procedure TForm1.Timer1Timer(Sender: TObject);
begin
JvLogFile1.Add(DateTimeToStr(Now), 'Now', DateTimeToStr(Now));
end;
執行程式後,可用文字編輯器開啟 Log File 'c:\log.txt'
Delphi JEDI Validate
需先安裝 JEDI VCL for Delphi
在 Form 中
放入 TMemo 顯示訊息
放入 TEdit 作為驗證資料輸入欄
放入 TButton 執行驗證
放入 Jv Validators -> TJvValidationSummary
放入 Jv Validators -> TJvErrorIndicator
放入 Jv Validators -> TJvValidators
修改 JvValidators1 屬性
ValidationSummary = JvValidationSummary1
ErrorIndicator = JvErrorIndicator1
用滑鼠雙擊 JvValidators1 元件會顯示 JvValidator Item Editor...
或是在JvValidators1 元件上用滑鼠右鍵選擇 JvValidator Item Editor...
新增一個 Required Field Validator
修改 JvRequiredFieldValidator1 屬性
ControlToValidate = Edit1
PropertyToValidate = 'Text'
ErrorMessage = 'Not Empty'
加入 Form1 OnCreate 事件
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
Edit1.Clear;
end;
加入 Button1 onclick 事件
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Clear;
if not JvValidators1.Validate then begin
Memo1.Lines := JvValidationSummary1.Summaries;
end;
end;
執行程式,按下 Button1 作驗證
Delphi 使用 TJclLocaleInfo
uses
JclLocales;
procedure TForm1.FormCreate(Sender: TObject);
var
info: TJclLocaleInfo;
begin
info := TJclLocaleInfo.Create;
try
with Memo1.Lines do
begin
Clear;
Add('CountryCode: ' + inttostr(info.CountryCode));
Add('CodePageANSI: ' + inttostr(info.CodePageANSI));
Add('EnglishLangName: ' + info.EnglishLangName);
Add('NativeLangName: ' + info.NativeLangName);
Add('LocalizedLangName: ' + info.LocalizedLangName);
Add('LocalizedCountryName: ' + info.LocalizedCountryName);
Add('ISOAbbreviatedLangName: ' + info.ISOAbbreviatedLangName);
Add('ISOAbbreviatedCountryName: ' + info.ISOAbbreviatedCountryName);
Add('DefaultLanguageId: ' + inttostr(info.DefaultLanguageId));
Add('LanguageIndentifier: ' + info.LanguageIndentifier);
end;
finally
info.Free;
end;
end;
{
CountryCode: 886
CodePageANSI: 950
EnglishLangName: Chinese
NativeLangName: 中文(繁體)
LocalizedLangName: 中文 (台灣)
LocalizedCountryName: 台灣
ISOAbbreviatedLangName: zh
ISOAbbreviatedCountryName: TW
DefaultLanguageId: 404
LanguageIndentifier: 0404
}
Deiphi 使用 JclDebug 來印出目前行號等資訊
Menu 上 Project->Options->Linker->Map file 選擇 Detailed 按 OK
uses
JclDebug;
procedure TForm1.FormCreate(Sender: TObject);
begin
with Memo1.Lines do
begin
Clear;
Add('FileName: ' + __FILE__);
Add(Format('Module: %s, Procedure %s, Line: %d', [
__MODULE__,
__PROC__,
__LINE__
]));
end;
end;
{
FileName: Unit1.pas
Module: Unit1, Procedure TForm1.FormCreate, Line: 35
}
Delphi TJclSCManager 列出及控制 Service
uses
JclSvcCtrl;
procedure TForm1.FormCreate(Sender: TObject);
var
I: Integer;
FSCManager: TJclSCManager;
Service: TJclNtService;
begin
FSCManager := TJclSCManager.Create;
try
FSCManager.Refresh(True);
Memo1.Lines.Clear;
Memo1.WordWrap := False;
for I := 0 to FSCManager.ServiceCount -1 do
begin
Service := FSCManager.Services[I];
Memo1.Lines.Values[Service.ServiceName] := Service.DisplayName;
end;
if FSCManager.FindService('Dhcp', Service) then begin
if Service.ServiceState = ssRunning then begin
Service.Stop;
ShowMessage('Stop Dhcp');
end;
Service.Start;
ShowMessage('Start Dhcp');
end;
finally
FSCManager.Free;
end;
end;
使用 Delphi JCL TEvaluator 動態計算公式
uses
JclExprEval;
procedure TForm1.FormCreate(Sender: TObject);
var
FEvaluator: TEvaluator;
begin
Memo1.Lines.Clear;
FEvaluator := TEvaluator.Create;
try
Memo1.Lines.Add(FloatToStr(FEvaluator.Evaluate('(3 + 5) * 10')));
finally
FEvaluator.Free;
end;
end;
{
80
}
2009年5月29日
Delphi JclFileUtils
uses
JclFileUtils;
procedure TForm1.FormCreate(Sender: TObject);
var
TempFileStream: TJclTempFileStream;
TempPath: string;
begin
// 建立暫存檔
TempFileStream := TJclTempFileStream.Create('~');
try
Memo1.Lines.Add(TempFileStream.FileName);
TempFileStream.Write('12345', 5);
TempFileStream.Seek(0, soBeginning);
Memo1.Lines.LoadFromStream(TempFileStream);
finally
TempFileStream.Free;
end;
TempPath := PathGetTempPath;
Memo1.Lines.Add(TempPath);
// 刪除檔案到資源回收筒
FileDelete( TempPath + '\~*.tmp', True);
// 刪除目錄到資源回收筒
DeleteDirectory(TempPath + '\dir', True);
end;
Delphi dll name
function Sto_GetModuleName: String;
var
szFileName: array[0..MAX_PATH] of Char;
begin
GetModuleFileName(hInstance, szFileName, MAX_PATH);
Result := szFileName;
end;
Delphi Windows Service - Indy Time Server
實做 Windows Service, 拿 Indy Time Server 元件來當服務範例
用 Delphi 先建立一個 Service Application
File->New->Other...-> [New page] Service Application
放入 TIdTimeServer 元件
Indy Servers -> IdTimeServer
修改 TService Properties (屬性)
Name = 'DelphiTimeServer'
DisplayName = 'Delphi Time Server'
加入 TService Events (事件)
// OnStart
procedure TDelphiTimeServer.ServiceStart(Sender: TService;
var Started: Boolean);
begin
IdTimeServer1.Active := True;
end;
// OnStop
procedure TDelphiTimeServer.ServiceStop(Sender: TService;
var Stopped: Boolean);
begin
IdTimeServer1.Active := False;
end;
儲存所有檔案 File -> Save All
建立並切換到專案目錄
例如 C:\Borland\Delphi7\Projects\TimeServer
更改預設檔案名稱
Unit1.pas -> TimeServerU.pas
Project1.dpr -> TimeServer.dpr
Complie Project 按 [Ctrl + F9] 編譯執行檔
專案目錄產生執行檔 TimeServer.exe
開啟 DOS 視窗(CMD)並切換到專案目錄
Start->Run...->CMD
例如專案目錄為 C:\Borland\Delphi7\Projects\TimeServer
> cd C:\Borland\Delphi7\Projects\TimeServer
安裝 TimeServer 服務
> TimeServer /install
若安裝成功, 會有對話框 Service installed successfully
啟動服務 DelphiTimeServer
> sc start DelphiTimeServer
SERVICE_NAME: DelphiTimeServer
TYPE : 10 WIN32_OWN_PROCESS
STATE : 2 START_PENDING
(NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0xb97071
WAIT_HINT : 0x1388
PID : 3764
FLAGS :
用 Delphi 建立 Time Client Application
File->New->Application
放入 TIdTime 元件
Indy Servers -> IdTime
修改 TIdTime Properties (屬性)
Host = 'localhost'
加入 TForm Events (事件)
// OnCreate
procedure TForm1.FormCreate(Sender: TObject);
begin
Showmessage(DateTimeToStr(IdTime1.DateTime));
end;
執行程式, 會有對話框顯示目前時間
停止服務 DelphiTimeServer
> sc stop DelphiTimeServer
SERVICE_NAME: DelphiTimeServer
TYPE : 10 WIN32_OWN_PROCESS
STATE : 3 STOP_PENDING
(STOPPABLE,PAUSABLE,ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x1388
移除 TimeServer 服務
> TimeServer /uninstall
若移除成功, 會有對話框 Service uninstalled successfully
Delphi Drop Files Components
下載並安裝 Misc component package
使用 TDropFiles 來讀取一個文字檔
在 Form 上放入 TMemo 和 TDropFiles 元件
在 DropFiles1 加入 Target 屬性為 Memo1
在 DropFiles1 加入 ondropFiles 事件
procedure TForm1.DropFiles1DropFiles(Sender: TObject; Files: TStrings; X,
Y: Integer);
var
FileName: string;
begin
FileName := Files[0];
if FileExists(FileName) then begin
Memo1.Lines.LoadFromFile(FileName);
end;
end;
執行程式後,可拖曳檔案總管中所列的文字檔
到程式 Memo 中
Delphi TNT Unicode Controls
Latest free version from TntWare 2.3.0
Delphi 7 SynEdit Export HTML
http://synedit.sourceforge.net/
在 Form 上按右鍵選擇 View as Text
或是按 [Alt + F12] 編輯 Delphi Form (DFM)
換掉原有 code, 貼入下列 code
object Form1: TForm1
Left = 193
Top = 129
Width = 507
Height = 301
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object SynEdit1: TSynEdit
Left = 0
Top = 29
Width = 499
Height = 234
Align = alClient
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Courier New'
Font.Style = []
TabOrder = 0
Gutter.Font.Charset = DEFAULT_CHARSET
Gutter.Font.Color = clWindowText
Gutter.Font.Height = -11
Gutter.Font.Name = 'Courier New'
Gutter.Font.Style = []
Gutter.ShowLineNumbers = True
Gutter.Gradient = True
Highlighter = SynPasSyn1
Lines.Strings = (
'procedure TForm1.FormCreate(Sender: TObject);'
'begin'
' ShowMessage(IntToStr(123)); '
' ShowMessage(md5sum(''c:\boot.ini'')); // FileName'
'end;')
end
object ToolBar1: TToolBar
Left = 0
Top = 0
Width = 499
Height = 29
ButtonHeight = 21
ButtonWidth = 68
Caption = 'ToolBar1'
ShowCaptions = True
TabOrder = 1
object ToolButton1: TToolButton
Left = 0
Top = 2
Caption = 'Export HTML'
ImageIndex = 0
onclick = ToolButton1Click
end
end
object SynPasSyn1: TSynPasSyn
CommentAttri.Foreground = clGreen
IdentifierAttri.Foreground = clNavy
NumberAttri.Foreground = clTeal
StringAttri.Foreground = clMaroon
Left = 8
Top = 40
end
object SynExporterHTML1: TSynExporterHTML
Color = clWindow
DefaultFilter = 'HTML Documents (*.htm;*.html)|*.htm;*.html'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Courier New'
Font.Style = []
Highlighter = SynPasSyn1
Title = 'Exported to file'
UseBackground = False
Left = 8
Top = 72
end
object SaveDialog1: TSaveDialog
DefaultExt = 'htm'
Left = 8
Top = 104
end
end
再按 [Alt + F12] 編輯 Object Pascal
換掉原有 code, 貼入下列 code
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, SynEditExport, SynExportHTML, SynEditHighlighter,
SynHighlighterPas, ComCtrls, ToolWin, SynEdit;
type
TForm1 = class(TForm)
SynEdit1: TSynEdit;
SynPasSyn1: TSynPasSyn;
ToolBar1: TToolBar;
ToolButton1: TToolButton;
SynExporterHTML1: TSynExporterHTML;
SaveDialog1: TSaveDialog;
procedure ToolButton1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ToolButton1Click(Sender: TObject);
begin
with SynExporterHTML1 do
begin
SaveDialog1.Filter := DefaultFilter;
if SaveDialog1.Execute then
begin
ExportAsText := True;
ExportAll(SynEdit1.Lines);
SynExporterHTML1.SaveToFile(SaveDialog1.FileName);
end;
end;
end;
end.
執行程式, 按 Export HTML
Delphi SynEdit 開發 IDE 元件
使用 Pascal highlighter
在 Form 上放入 SynEdit -> TSynEdit 和 SynEdit Highlighters -> TSynPasSyn
在 Form OnCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
with SynPasSyn1 do
begin
// set color
CommentAttri.Foreground := clGreen;
IdentifierAttri.Foreground := clNavy;
NumberAttri.Foreground := clBlue;
StringAttri.Foreground := clBlue;
end;
// set Highlighter
SynEdit1.Highlighter := SynPasSyn1;
with SynEdit1.Lines do
begin
// add Pascal code
Add('// Delphi source code');
Add('function StrToInt(const S: string): Integer;');
Add('var');
Add(' E: Integer;');
Add('begin');
Add(' Val(S, Result, E);');
Add(' if E <> 0 then ConvertErrorFmt(@SInvalidInteger, [S]);');
Add('end;');
end;
end;
Delphi 使用 Microsoft Agent
http://zewaren.developpez.com/delphi/ms-agents/
Delphi Indy 取得本機(localhost) IP
procedure TForm1.FormCreate(Sender: TObject);
begin
ShowMessage(IdIPWatch1.LocalIP);
end;
Delphi 使用 Indy 取得檔案 md5sum
uses
IdHashMessageDigest, IdHash;
function md5sum(FileName: string): string;
var
MyMD5: TIdHashMessageDigest5;
Digest: T4x4LongWordRecord;
Stream: TStream;
begin
if FileExists(FileName) then begin
MyMD5 := TIdHashMessageDigest5.Create;
Stream := TFileStream.Create(FileName, fmOpenRead);
try
Digest := MyMD5.HashValue(Stream);
Result := MyMD5.AsHex(Digest);
finally
Stream.Free;
MyMD5.Free;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ShowMessage(md5sum('c:\boot.ini')); // FileName
end;
Delphi 使用 Indy 取得超過 2G FILE SIZE
uses IdGlobalProtocols;
procedure TForm1.FormCreate(Sender: TObject);
begin
ShowMessage(IntToStr(FileSizeByName('FILE_NAME')));
end;
Delphi 使用 Windows API FindFirstFile 取得超過 2G FILE SIZE
function FileSize(const FileName: String): Int64;
var
LHFile: THandle;
lpFindFileData: TWin32FindData;
PSIZE: PULargeInteger;
begin
Result := 0;
LHFile := Windows.FindFirstFile(PChar(FileName), lpFindFileData);
if (LHFile <> INVALID_HANDLE_VALUE) then
begin
Windows.FindClose(LHFile);
PSIZE := @Result;
PSIZE.LowPart := lpFindFileData.nFileSizeLow;
PSIZE.HighPart := lpFindFileData.nFileSizeHigh;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
FileName: string;
begin
FileName := 'FileName'; // FileName
ShowMessage(IntToStr(FileSize(FileName)));
end;
Delphi 使用 Windows API GetFileSizeEx 取得超過 2G FILE SIZE
function GetFileSizeEx(hFile: THandle; lpFileSize: PLargeInteger): BOOL; stdcall; external kernel32 name 'GetFileSizeEx';
function FileSizeEx(const FileName: String): Int64;
var
LHFile: THandle;
begin
Result := 0;
LHFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
if (LHFile <> INVALID_HANDLE_VALUE) then
begin
GetFileSizeEx(LHFile, @Result);
CloseHandle(LHFile);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ShowMessage(IntToStr(FileSizeEx('FileName'))); // FileName
end;
Delphi 使用 TLHelp32 列出 目前執行緒
uses
TLHelp32;
procedure TForm1.FormCreate(Sender: TObject);
var
hProcessSnap: THandle;
ProcessEntry32: TProcessEntry32;
procedure ShowProcess32;
begin
with Memo1.Lines do begin
Add(Format(
'%s ProcessID: %d ParentProcessID: %d Threads: %d Priority: %d',
[
ProcessEntry32.szExeFile,
ProcessEntry32.th32ProcessID,
ProcessEntry32.th32ParentProcessID,
ProcessEntry32.cntThreads,
ProcessEntry32.pcPriClassBase
]));
end;
end;
begin
hProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap = INVALID_HANDLE_VALUE) then Exit;
try
ProcessEntry32.dwSize := SizeOf(ProcessEntry32);
if Process32First(hProcessSnap, ProcessEntry32) then begin
ShowProcess32;
repeat
ShowProcess32;
until not Process32Next(hProcessSnap, ProcessEntry32);
end;
finally
CloseHandle(hProcessSnap);
end;
end;
Delphi MSXML DOM XPath
{
XPath 參考網頁
http://www.w3.org/TR/xpath
在 uses 中加入 msxml, msxmldom
}
uses
msxml, msxmldom;
{
在 Form 上放一個 TMemo
在 FormCreate 事件中加入
}
procedure TForm1.FormCreate(Sender: TObject);
var
DOMDocument: IXMLDOMDocument;
begin
with memo1.Lines do
begin
Clear;
Add('<?xml version="1.0" encoding="Big5"?>');
Add('<html lang="en">');
Add(' <head>');
Add(' <title>Extensible Markup Language (XML)</title>');
Add(' </head>');
Add(' <body>');
Add(' <a href="1">first</a>');
Add(' <a href="2">second</a>');
Add(' </body>');
Add('</html>');
end;
DOMDocument := CreateDOMDocument;
DOMDocument.loadXML(memo1.Lines.Text);
with DOMDocument, Memo1.Lines do
begin
Clear;
Values['title'] := selectSingleNode('/html/head/title/text()').nodeValue;
Values['All Tag Count'] := IntToStr(selectNodes('//*').length);
Values['body Tag child Nodes Count'] := IntToStr(selectNodes('/*/body/*').length);
Values['a Tag Count'] := IntToStr(selectNodes('//a').length);
Values['First a Tag Text'] := selectSingleNode('//a[1]/text()').nodeValue;
Values['First a Tag href'] := selectSingleNode('//a[1]/@href').nodeValue;
Values['href equal 2 Text'] := selectSingleNode('//a[@href=2]/text()').nodeValue;
end;
end;
{
title=Extensible Markup Language (XML)
All Tag Count=6
body Tag child Nodes Count=2
a Tag Count=2
First a Tag Text=first
First a Tag href=1
href equal 2 Text=second
}
Delphi 使用 XML Mapper 來建立 Transformation File,並顯示資料表
放到 project 中 msnmsg.xml
使用 Tools->XML Mapper
File->Open-> msnmsg.xml
在左方 Document 中 Select Message[*]
按右鍵 Select All Children
Create->Datapacket from XML
Create->Transformation
File->Save->Transformation
存到 project 中 ToDp.xtr
在 Form 中加入元件
DataAccess->TXMLTransformProvider
DataAccess->TClientDataSet
DataAccess->TDataSource
Data Controls->TDBGrid
Data Controls->TDBNavigator
在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
DBGrid1.Align := alClient;
DBNavigator1.Align := alBottom;
XMLTransformProvider1.XMLDataFile := 'msnmsg.xml';
XMLTransformProvider1.TransformRead.TransformationFile := 'ToDp.xtr';
ClientDataSet1.ProviderName := 'XMLTransformProvider1';
DataSource1.DataSet := ClientDataSet1;
DBGrid1.DataSource := DataSource1;
DBNavigator1.DataSource := DataSource1;
ClientDataSet1.Active := True;
end;
Delphi TXMLDocument XPath
http://www.w3.org/TR/xpath
在 Form 上放一個 TMemo 和 Internet TXMLDocument
在 FormCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
SNode: IDOMNodeSelect;
begin
with XMLDocument1.XML do
begin
Add('<?xml version="1.0" encoding="Big5"?>');
Add('<html lang="en">');
Add(' <head>');
Add(' <title>Extensible Markup Language (XML)</title>');
Add(' </head>');
Add(' <body>');
Add(' <a href="1">first</a>');
Add(' <a href="2">second</a>');
Add(' </body>');
Add('</html>');
end;
XMLDocument1.Active := True;
with XMLDocument1.DOMDocument, Memo1.Lines do
begin
Clear;
SNode := documentElement as IDOMNodeSelect;
Values['title'] := SNode.selectNode('/html/head/title/text()').nodeValue;
Values['All Tag Count'] := IntToStr(SNode.selectNodes('//*').length);
Values['body Tag child Nodes Count'] := IntToStr(SNode.selectNodes('/*/body/*').length);
Values['a Tag Count'] := IntToStr(SNode.selectNodes('//a').length);
Values['First a Tag Text'] := SNode.selectNode('//a[1]/text()').nodeValue;
Values['First a Tag href'] := SNode.selectNode('//a[1]/@href').nodeValue;
Values['href equal 2 Text'] := SNode.selectNode('//a[@href=2]/text()').nodeValue;
end;
end;
{
title=Extensible Markup Language (XML)
All Tag Count=6
body Tag child Nodes Count=2
a Tag Count=2
First a Tag Text=first
First a Tag href=1
href equal 2 Text=second
}
Delphi 寫 DLL 程式
function Echo(pw: PWideChar): PWideChar; stdcall; external 'Project2.dll';
在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
w: PWideChar;
begin
w := PWideChar(UTF8Decode(#$E4#$BD#$A0#$E5#$A5#$BD)); // 你好 UTF-8
MessageBoxW(0, Echo(w), w, MB_OK);
end;
按【Ctrl + Alt + F11】 叫出 Project Manager
按右鍵 Add New Project...
New DLL Wizard
產生 library Project2
在 begin 之前加入
function Echo(pw: PWideChar): PWideChar; stdcall; export;
const
c: array[0..1] of WideChar = (WideChar($56DE), WideChar($50B3)); // 回傳 Unicode
var
w: WideString;
begin
w := c;
w := w + ': ' + pw;
Result := PWideChar(w);
end;
exports Echo;
編譯 Project2.dll 和 程式 Project1.exe
Project-> Bulid All Projects
執行 Project1.exe
Delphi 使用 WSDLImp 來建立 WebService Client Source Code
可產生 WebService Client Source Code
>WSDLImp
...
Usage: WSDLIMP [options] <WSDL[File|URL]|UDDI BindingKey>
Code Generation Options:
-C Generate C++ code -P Generate Pascal code
-R:name1;name2;name3 - Make out parameters with these names the return type
[ -option{+|-} default shown ]
-Oa- Map ambiguous classes to arrays -Oo+ One out param becomes return
-Ob- Use XMLBinding Manager for Schemas -Oq- Quiet mode (Suppress Headers)
-Od+ Generate Complex Type Destructors -Og- Use OLE GUIDs for interface
-Of- Process Faults -Os- Generate Server skeleton code
-Oi- Ignore Schema errors -Ot- Output unused types
-Ok+ Map named arrays to classes -Ou+ Unwind Literal Parameters
-Ol- Generate Literal types -Ov+ Verbose Info. in file
-On- Declare Types in Namespace -Ow+ Map strings to WideStrings
-Ox- Collapse simple Aliases
Other options:
-D<path> Output directory path -=+ Output filename after'=' in URL
-U<url of UDDI Registry> UDDI Registry [NOTE: input must be UDDI bindingkey(s)
@<Resp> Response file with list of WSDL|UDDIBindingKey to import
Proxy/Server Authentication:
-user:userName -pass:Password [-proxy:Proxy]
>WSDLImp http://api.google.com/GoogleSearch.wsdl
...
Reading: http://api.google.com/GoogleSearch.wsdl
Writing: GoogleSearch.pas
----------------------------------------------------------------------
uses
GoogleSearch;
procedure TForm1.FormCreate(Sender: TObject);
var
gs: GoogleSearchPort;
sr: GoogleSearchResult;
ra: ResultElementArray;
r: ResultElement;
I: Integer;
begin
gs := GetGoogleSearchPort(False,'http://api.google.com/search/beta2');
sr := gs.doGoogleSearch(
'?', // Google SOAP Search API 的 Key, 2006-12-05 日停發
'台中市', // query
0 ,2, // start, maxResults
False, // filter
'countryTW', //restrict 台灣地區
False, // safeSearch
'lang_zh-TW', // lr 繁體字
'UTF-8', // ie
'UTF-8'); // oe
with Memo1.Lines do
begin
Clear;
Add(FloatToStr(sr.searchTime));
ra := sr.resultElements;
for I := Low(ra) to High(ra) do
begin
r := ra[I];
Add(r.title);
Add(r.URL);
Add(r.snippet);
end;
end;
end;
{
0.019577
<b>台中市</b>政府.全球資訊網
http://www.tccg.gov.tw/
提供市府介紹、市政公告、活動、新聞、社會福利、生活資訊等。
<b>台中市</b>教育局
http://www.tceb.edu.tw/
含教育局網路導覽、公告、討論區以及各類研習線上報名系統。
}
Delphi 以WideString來做字集轉換
function WideStringToStr(CodePage: UINT; WStr: WideString): string;
var
Len: Integer;
begin
Len := WideCharToMultiByte(CodePage, 0, PWChar(WStr), -1, nil, 0, nil, nil);
SetLength(Result, Len);
WideCharToMultiByte(CodePage, 0, PWChar(WStr), Len, PChar(Result), Len, nil, nil);
end;
function StrToWideString(CodePage: UINT; Str: string): WideString;
begin
SetLength(Result, Length(Str));
MultiByteToWideChar(CodePage, MB_COMPOSITE, PChar(Str), -1, PWChar(Result), Length(Str));
end;
Delphi 使用 convert 將 DFM 二進位檔轉成文字檔
>convert
...
Usage: convert.exe [-i] [-s] [-t | -b]
-i Convert files in-place (output overwrites input)
-s Recurse subdirectories
-t Convert to text
-b Convert to binary
>cd [Project]
>convert -i -s -t *.DFM
Delphi 畫貝塞爾(Bezier)曲線
procedure TForm1.FormPaint(Sender: TObject);
var
Points: array of TPoint;
begin
Canvas.Pen.Width := 3;
Setlength(Points, 4);
Points[0].X := 0;
Points[0].y := 0;
Points[1].X := 0;
Points[1].y := 100;
Points[2].X := 150;
Points[2].y := 50;
Points[3].X := 150;
Points[3].y := 150;
Canvas.PolyBezier(Points);
Points[0].X := 150;
Points[0].y := 150;
Points[1].X := 150;
Points[1].y := 200;
Points[2].X := 200;
Points[2].y := 250;
Points[3].X := 250;
Points[3].y := 250;
Canvas.PolyBezier(Points);
end;
Delphi 使用 TWebBrowser
在 Form 上放入 Internet -> TWebBrowser
procedure TForm1.FormCreate(Sender: TObject);
var
Browser: Variant;
Document: Variant;
begin
WebBrowser1.Align := alClient;
Browser := WebBrowser1.OleObject;
Browser.navigate('about:blank');
Document := Browser.document;
Document.open;
Document.writeln('<html>');
Document.writeln('<body bgcolor=#000000 text=#ffffff>');
Document.writeln('Hello World!');
Document.writeln('</body>');
Document.writeln('</html>');
Document.close;
end;
Delphi TADODataSet Save To File Load From File
放入 TADODataSet、TDataSource、TDBGrid
procedure TForm1.FormCreate(Sender: TObject);
begin
DataSource1.DataSet := ADODataSet1;
DBGrid1.DataSource := DataSource1;
DBGrid1.Align := alClient;
with ADODataSet1 do
begin
ConnectionString :=
'FILE NAME=C:\Program Files\Common Files\System\Ole DB\Data Links\DBDEMOS.udl';
CommandText := 'select * from country';
Active := True;
// 存入檔案
SaveToFile('country.adtg');
// 關掉連線
Close;
ConnectionString := '';
CommandText := '';
// 從檔案中載入資料
LoadFromFile('country.adtg');
end;
end;
Delphi 使用 ShellExecute 顯示 GoogleMaps
在 Button1 Click 事件中加入
uses
ShellAPI;
procedure TForm1.Button1Click(Sender: TObject);
var
url: string;
begin
url := 'http://maps.google.com/maps?ll=' +
EdtLatitude.Text + ',' +
EdtLongitude.Text;
ShellExecute(Handle, nil, PAnsiChar(url), nil, nil, SW_SHOWNORMAL);
end;
執行程式後,輸入 Latitude 及 Longitude 按 Button1 後就可顯示 Google 的地圖了
Delphi 程式設計工具
http://www.gexperts.org/
CnPack IDE 專家包(CnWizards)是一組集成在 Delphi/C++ Builder 的 IDE 中,用於增強 IDE 功能、提高 IDE 的可用性及開發效率的工具
http://www.cnpack.org
Delphi 多執行序控制
type
// 宣告執行序
TTestThread = class(TThread)
private
FStrings: TStrings;
procedure AddToStrings;
class procedure Buttonclick(Sender: TObject);
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean; Strings: TStrings);
end;
var
TestThread1, TestThread2: TTestThread;
// 列出執行序的 ThreadID
procedure TTestThread.AddToStrings;
begin
FStrings.Add('ThreadID: ' + IntToStr(ThreadID));
end;
class procedure TTestThread.Buttonclick(Sender: TObject);
begin
with Sender as TToolButton do
begin
if Down then begin
// 執行
TTestThread(Tag).Resume;
end else begin
// 暫停
TTestThread(Tag).Suspend;
end;
end;
end;
{
CreateSuspended 建立時先不執行
Strings 要列出訊息的 Strings
}
constructor TTestThread.Create(CreateSuspended: Boolean; Strings: TStrings);
begin
inherited Create(CreateSuspended);
FStrings := Strings;
end;
procedure TTestThread.Execute;
begin
// 當未停止時列出執行序的 ThreadID
while not Terminated do
begin
Synchronize(AddToStrings);
Sleep(1000);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
ToolBar: TToolBar;
begin
// 建立 TMemo
with TMemo.Create(Self) do
begin
Parent := Self;
Align := alClient;
Clear;
// 印出主執行序 MainThreadID
Lines.Add(IntToStr(MainThreadID));
// 建立執行序,並在建立時就執行運作
TestThread1 := TTestThread.Create(False, Lines);
TestThread2 := TTestThread.Create(False, Lines);
end;
// 建立 TToolBar
ToolBar := TToolBar.Create(Self);
with ToolBar do
begin
Parent := Self;
ShowCaptions := True;
with TToolButton.Create(Self) do
begin
Parent := ToolBar;
Caption := 'TestThread2';
Tag := Integer(TestThread2);
onclick := TTestThread.Button click;
Style := tbsCheck;
Down := True;
end;
with TToolButton.Create(Self) do
begin
Parent := ToolBar;
Caption := 'TestThread1';
Tag := Integer(TestThread1);
onclick := TTestThread.Button click;
Style := tbsCheck;
Down := True;
end;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// 停止執行序
with TestThread1 do
begin
if Suspended then begin
Resume;
Terminate;
end
end;
with TestThread2 do
begin
if Suspended then begin
Resume;
Terminate;
end
end;
TestThread1.Free;
TestThread2.Free;
end;
Delphi Thread
type
// 宣告執行序
TTestThread = class(TThread)
private
FStrings: TStrings;
procedure AddToStrings;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean; Strings: TStrings);
end;
// 列出執行序的 ThreadID
procedure TTestThread.AddToStrings;
begin
FStrings.Add('ThreadID: ' + IntToStr(ThreadID));
end;
{
CreateSuspended 建立時先不執行
Strings 要列出訊息的 Strings
}
constructor TTestThread.Create(CreateSuspended: Boolean; Strings: TStrings);
begin
inherited Create(CreateSuspended);
FStrings := Strings;
end;
procedure TTestThread.Execute;
begin
// 當未停止時列出執行序的 ThreadID
while not Terminated do
begin
Synchronize(AddToStrings);
Sleep(1000);
end;
end;
var
TestThread: TTestThread;
procedure TForm1.FormCreate(Sender: TObject);
begin
// 印出主執行序 MainThreadID
Memo1.Lines.Add('MainThreadID: ' + IntToStr(MainThreadID));
// 建立執行序,並在建立時就執行運作
TestThread := TTestThread.Create(False, Memo1.Lines);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// 停止執行序
TestThread.Terminate;
TestThread.Free;
end;
Delphi MSXML DOM XSLT 轉換
{
XSLT 參考網頁
http://www.w3.org/TR/xslt
在 uses 中加入 msxml, msxmldom
}
uses
msxml, msxmldom;
{
在 Form 上放一個 TMemo
在 FormCreate 事件中加入
}
procedure TForm1.FormCreate(Sender: TObject);
var
DOMDocument: IXMLDOMDocument;
Data: IXMLDOMDocument;
begin
// 資料
with memo1.Lines do
begin
Clear;
Add('<?xml version="1.0" encoding="Big5"?>');
Add('<data>');
Add(' <title>Extensible Markup Language (XML)</title>');
Add(' <text>first</text>');
Add(' <text>second</text>');
Add('</data>');
end;
Data := CreateDOMDocument;
Data.loadXML(memo1.Lines.Text);
// 樣板
with memo1.Lines do
begin
Clear;
Add('<?xml version="1.0" encoding="Big5"?>');
Add('<xsl:stylesheet version="1.0" ');
Add(' xmlns:xsl="http://www.w3.org/1999/XSL/Transform">');
Add('<xsl:template match="data">');
Add(' <html>');
Add(' <head>');
Add(' <title><xsl:value-of select="title"/></title>');
Add(' </head>');
Add(' <body>');
Add(' <xsl:for-each select="text">');
Add(' <li><xsl:value-of select="text()"/></li>');
Add(' </xsl:for-each>');
Add(' </body>');
Add(' </html>');
Add('</xsl:template>');
Add('</xsl:stylesheet>');
end;
DOMDocument := CreateDOMDocument;
DOMDocument.loadXML(memo1.Lines.Text);
// 轉換
Memo1.Lines.Text := Data.transformNode(DOMDocument.documentElement);
end;
{ Memo1
<html>
<head>
<META http-equiv="Content-Type" content="text/html">
<title>Extensible Markup Language (XML)</title>
</head>
<body>
<li>first</li>
<li>second</li>
</body>
</html>
}
使用 Delphi SHFileOperationW 刪除檔案到資源回收筒
uses
ShellAPI;
procedure TForm1.FormCreate(Sender: TObject);
var
FileOpStrucW: TSHFileOpStructW;
F1, F2: PWideChar;
begin
F1 := PWideChar(WideString('C:\f1.txt'));
F2 := PWideChar(WideString('C:\temp.txt'));
FileOpStrucW.Wnd := Application.Handle;
with FileOpStrucW do
begin
wFunc := FO_COPY; // 複製
pFrom := F1;
pTo := F2;
fFlags := 0;
end;
SHFileOperationW(FileOpStrucW);
with FileOpStrucW do
begin
wFunc := FO_DELETE; // 刪除
pFrom := F2;
pTo := nil;
fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION; // 直接丟進 RecycleBin
end;
SHFileOperationW(FileOpStrucW);
end;
JEDI VCL for Delphi
JEDI VCL for Delphi
http://sourceforge.net/projects/jvcl
下載後執行安裝
\jcl\Install.bat
\jvcl\install.bat
使用 JclSysInfo 取得環境變數
uses
JclSysInfo;
procedure TForm1.FormCreate(Sender: TObject);
begin
GetEnvironmentVars(Memo1.Lines);
ShowMessage(GetWindowsFolder);
end;
Delphi 以類別名稱來建立有建構參數的物件
type
// ...
TMyParent = class(TComponent)
public
function echo(name: string): string; virtual; abstract;
end;
TMyParentClass = class of TMyParent;
TMySub1 = class(TMyParent)
private
s: string;
public
constructor Create(AOwner: TComponent); override;
function echo(name: string): string; override;
end;
// ...
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
PClass: TPersistentClass;
Obj: TMyParent;
begin
RegisterClass(TMySub1);
PClass := FindClass('TMySub1');
Obj := TMyParentClass(PClass).Create(Self);
Caption := Obj.echo('Solnone');
UnRegisterClass(TMySub1);
end;
constructor TMySub1.Create(AOwner: TComponent);
begin
s := AOwner.GetNamePath + ' TMySub1 ';
end;
function TMySub1.echo(name: string): string;
begin
Result := s+ 'Hello ' + name;
end;
// Form1 TMySub1 Hello Solnone
使用 Delphi DCC32 Compiler
在 命令提示字元 (cmd) 中可以用 DCC32 來 Compiler Delphi 程式!
它的設定檔為 DCC32.CFG ,內容為預設參數,可用 notepad 編輯
-aWinTypes=Windows;WinProcs=Windows;DbiProcs=BDE;DbiTypes=BDE;DbiErrs=BDE
-u"C:\Delphi7\lib";"C:\Delphi7\lib\Obj"
在 cmd 中輸入 DCC32 --help 列出可用的參數
>dcc32 --help
Syntax: dcc32 [options] filename [options]
-A<unit>=<alias> = Set unit alias -LU<package> = Use package
-B = Build all units -M = Make modified units
-CC = Console target -N<path> = DCU output directory
-CG = GUI target -O<paths> = Object directories
-D<syms> = Define conditionals -P = look for 8.3 file names also
-E<path> = EXE output directory -Q = Quiet compile
-F<offset> = Find error -R<paths> = Resource directories
-GD = Detailed map file -U<paths> = Unit directories
-GP = Map file with publics -V = Debug information in EXE
-GS = Map file with segments -VR = Generate remote debug (RSM)
-H = Output hint messages -W = Output warning messages
-I<paths> = Include directories -Z = Output 'never build' DCPs
-J = Generate .obj file -$<dir> = Compiler directive
-JP = Generate C++ .obj file --help = Show this help screen
-K<addr> = Set image base addr --version = Show name and version
Compiler switches: -$<letter><state> (defaults are shown below)
A8 Aligned record fields P+ Open string params
B- Full boolean Evaluation Q- Integer overflow checking
C+ Evaluate assertions at runtime R- Range checking
D+ Debug information T- Typed @ operator
G+ Use imported data references U- Pentium(tm)-safe divide
H+ Use long strings by default V+ Strict var-strings
I+ I/O checking W- Generate stack frames
J- Writeable structured consts X+ Extended syntax
L+ Local debug symbols Y+ Symbol reference info
M- Runtime type info Z1 Minimum size of enum types
O+ Optimization
編譯 Project1.dpr
>dcc32 Project1.dpr
\Project1.dpr(14)
15 lines, 0.22 seconds, 342368 bytes code, 7657 bytes data.
使用 TStrings CommaText 和 DelimitedText 組合字串
procedure TForm1.FormCreate(Sender: TObject);
var
Strs: TStrings;
begin
Strs := TStringList.Create;
try
with Strs do
begin
Add('String'' 1');
Add('String" 2');
Add('String 3');
QuoteChar := '''';
Delimiter := ',';
end;
with Memo1.Lines do
begin
Clear;
Values['CommaText'] := Strs.CommaText;
Add('SQL Strings');
Add('INSERT INTO TABLE1 (FIELD1, FIELD2, FIELD3)');
Add('VALUES (' + Strs.DelimitedText + ')');
end;
finally
Strs.Free;
end;
end;
{
CommaText="String' 1","String"" 2","String 3"
SQL Strings
INSERT INTO TABLE1 (FIELD1, FIELD2, FIELD3)
VALUES ('String'' 1','String" 2','String 3')
}
Delphi 取出資料庫欄位值的方法
在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
Index: Integer;
begin
with Query1, Memo1 do
begin
Lines.Clear;
DatabaseName := 'DBDEMOS';
SQL.Clear;
SQL.Add('SELECT NAME, CAPITAL, CONTINENT, AREA, POPULATION');
SQL.Add(' FROM COUNTRY');
SQL.Add(' WHERE NAME = ' + QuotedStr('Argentina'));
Active := True;
// 列出所有欄位名稱
Lines.Add('-- List Field Name --');
Lines.AddStrings(FieldList);
if IsEmpty then
Exit;
Lines.Add('-- Get Field Value --');
while not Eof do
begin
// 以 field name 取出值
Lines.Add(VarToStr(FieldByName('NAME').AsVariant));
Lines.Add(VarToStr(FindField('CAPITAL').AsVariant));
Lines.Add(VarToStr(FindField('CONTINENT').AsVariant));
Lines.Add(VarToStr(FieldValues['AREA']));
//
// 以 field index 取出 POPULATION 值
Index := FieldList.IndexOf('POPULATION');
Lines.Add(VarToStr(Fields[Index].AsVariant));
Lines.Add(VarToStr(FieldList[Index].AsVariant));
Next;
end;
end;
end;
{
-- List Field Name --
NAME
CAPITAL
CONTINENT
AREA
POPULATION
-- Get Field Value --
Argentina
Buenos Aires
South America
2777815
32300003
32300003
}
Delphi 使用 FindGlobalComponent 來取得 Form
先 new 一個 Form2
在 Form2 Create 事件中加入
procedure TForm2.FormCreate(Sender: TObject);
begin
(FindGlobalComponent('Form1') as TForm).Caption := 'Show From Form2';
end;
執行程式後 Form1 的 Caption 會被改成 Show From Form2
Delphi 使用 TShellChangeNotifier 得知目錄中的檔案異動
在 Form 上放入這二個元件
在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
with ShellListView1 do
begin
Align := alClient;
ViewStyle := vsReport;
Root := 'C:\'; // 要顯示的目錄
end;
with ShellChangeNotifier1 do
begin
WatchSubTree := False;
Root := ShellListView1.Root; // 要偵測的目錄
end;
end;
在 ShellChangeNotifier1 Change 事件中加入
procedure TForm1.ShellChangeNotifier1Change;
begin
ShellListView1.Refresh; // 更新 ListView
Application.ProcessMessages;
ShowMessage('Change');
end;
使用 Delphi TFrame
TFrame 可以將一些常用的元件事先做排版,或是寫入共用method 等
例如常要顯示資料庫中的 Table 時
選 Menu File->New->Frame 來加入一個 Frame2
可將 TTable,TDataSource,TDBGrid,TDBNavigator 放入 Frame2 中
先設好關連
DataSource1.DataSet := Table1;
DBGrid1.DataSource := DataSource1;
DBNavigator1.DataSource := DataSource1;
在 Form1 上放入二個以上的 Frame2 (在元件面版上 Standard -> Frames, 選擇 Frame2 後按 OK)
就可以分別設定 Frame 中 Table1 的 DatabaseName 和 TableName 來顯示不同的 Table
Delphi 的四捨五入
uses
Math;
// 參考 SimpleRoundTo 來寫的四捨五入,和 format 的結果相同
function MyRoundTo(const AValue: Extended; const ADigit: TRoundToRange = -2): Extended;
var
LFactor: Extended;
f: Extended;
begin
LFactor := IntPower(10, ADigit);
if AValue < 0 then
f := -0.5
else
f := 0.5;
Result := Trunc((AValue / LFactor) + f) * LFactor;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
with Memo1.Lines do
begin
Clear;
Add('RoundTo 0.12345 小數四位 = ' + FloatToStr(RoundTo(0.12345, -4)));
Add('RoundTo -0.12345 小數四位 = ' + FloatToStr(RoundTo(-0.12345, -4)));
Add('RoundTo 123450 捨十位 = ' + FloatToStr(RoundTo(123450, 2)));
Add('SimpleRoundTo 0.12345 小數四位 = ' + FloatToStr(SimpleRoundTo(0.12345, -4)));
Add('SimpleRoundTo -0.12345 小數四位 = ' + FloatToStr(SimpleRoundTo(-0.12345, -4)));
Add('SimpleRoundTo 123450 捨十位 = ' + FloatToStr(SimpleRoundTo(123450, 2)));
Add('MyRoundTo 0.12345 小數四位 = ' + FloatToStr(MyRoundTo(0.12345, -4)));
Add('MyRoundTo -0.12345 小數四位 = ' + FloatToStr(MyRoundTo(-0.12345, -4)));
Add(Format('Format 0.12345 小數四位 = %.4f', [0.12345]));
Add(Format('Format -0.12345 小數四位 = %.4f', [-0.12345]));
end;
end;
{ Memo1 的結果
RoundTo 0.12345 小數四位 = 0.1234
RoundTo -0.12345 小數四位 = -0.1234
RoundTo 123450 捨十位 = 123400
SimpleRoundTo 0.12345 小數四位 = 0.1234
SimpleRoundTo -0.12345 小數四位 = -0.1233
SimpleRoundTo 123450 捨十位 = 123500
MyRoundTo 0.12345 小數四位 = 0.1235
MyRoundTo -0.12345 小數四位 = -0.1235
Format 0.12345 小數四位 = 0.1235
Format -0.12345 小數四位 = -0.1235
}
Delphi TListView 的排序
在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
with ListView1 do
begin
ViewStyle := vsReport;
Columns.Add.Caption := 'A';
Columns.Add.Caption := 'B';
with Items.Add do
begin
Caption := '3';
SubItems.Add('3');
end;
with Items.Add do
begin
Caption := '2';
SubItems.Add('1');
end;
with Items.Add do
begin
Caption := '1';
SubItems.Add('2');
end;
end;
end;
在 TForm1 的 private 宣告中加入
private
SortColumn: TListColumn; // 排序欄位
在 TListView ColumnClick 事件中加入
procedure TForm1.ListView1ColumnClick(Sender: TObject;
Column: TListColumn);
begin
SortColumn := Column;
(Sender as TCustomListView).AlphaSort; // 排序
SortColumn.Tag := not SortColumn.Tag; // tag 紀錄正反排
end;
在 TListView Compare 事件中加入
procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem;
Data: Integer; var Compare: Integer);
var
ix: Integer;
begin
if SortColumn.Index = 0 then
Compare := CompareText(Item1.Caption, Item2.Caption)
else begin
ix := SortColumn.Index - 1;
Compare := CompareText(Item1.SubItems[ix], Item2.SubItems[ix]);
end;
if Boolean(SortColumn.Tag) then begin
Compare := -Compare; // 反排
end;
end;
執行程式後,就可用滑鼠按 ListView 的 Column Header 來做正反排
Delphi ShellExecute 執行外部程式
uses
ShellAPI;
procedure TForm1.FormCreate(Sender: TObject);
begin
// 執行 notepad
ShellExecute(Handle, nil, 'notepad', nil, nil, SW_SHOWNORMAL);
// 打開 word 檔
ShellExecute(Handle, 'oppen', 'C:\a.doc', nil, nil, SW_SHOWNORMAL);
// 列印 excel 檔
ShellExecute(Handle, 'print', 'C:\a.xls', nil, nil, SW_SHOWNORMAL);
// 開網頁
ShellExecute(Handle, nil, 'http://www.borland.com/', nil, nil, SW_SHOWNORMAL);
// 寄信
ShellExecute(Handle, nil, 'mailto:name@host.com?subject=主旨&body=內文', nil, nil, SW_SHOWNORMAL);
end;
Delphi 單位換算 Convert Function
uses
StdConvs, ConvUtils;
在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
// 攝氏 23 -> 華氏 73.4
ShowMessage(FloatToStr(CelsiusToFahrenheit(23)));
// 華氏 73.4 -> 攝氏 23
ShowMessage(FloatToStr(FahrenheitToCelsius(73.4)));
// 攝氏 23 -> 華氏 73.4
ShowMessage(FloatToStr(Convert(23, tuCelsius , tuFahrenheit)));
// 1 年 -> 365.25 天
ShowMessage(FloatToStr(Convert(1, tuYears , tuDays)));
// 1 kg -> 1000 g
ShowMessage(FloatToStr(Convert(1, muKilograms , muGrams)));
// 1 公尺 -> 100 公分
ShowMessage(FloatToStr(Convert(1, duMeters , duCentimeters)));
end;
Delphi To-Do List
procedure TForm1.FormCreate(Sender: TObject);
var
Strings: TStrings;
begin
Strings := typename.Create;
try
// 在此按【Ctrl+Shift+T】叫出 Add To-Do Item
// 或是按滑鼠右鍵選 Add To-Do Item
// 在 Text: 輸入 Add Text to Strings
// 在 Priority: 輸入 1
// 在 Owner: 輸入 UserName
// 在 Category: 輸入 Normal
finally
Strings.Free;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
Strings: TStrings;
begin
Strings := typename.Create;
try
{ TODO 1 -oUserName -cNormal : Add Text to Strings}
finally
Strings.Free;
end;
end;
在功能表 View -> To-Do List 中可以看到所有的 To-Do Item
並可加以排序、修改、匯出 Html 報表等,做完的 Item 可以打勾變成 DONE
Delphi 動態取得及設定物件的屬性,使用 ObjAuto
uses
ObjAuto ,TypInfo;
在 Form 上放入一個 TMemo
將 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
PropList: PPropList;
Count, i: Integer;
PropInfo: PPropInfo;
PropName: string;
Value: Variant;
begin
ShowHint := True;
Memo1.Clear;
// 動態設定物件的屬性 Memo1.Hint := 'test SetPropValue';
SetPropValue(Memo1, 'Hint', 'test SetPropValue');
Count := GetPropList(Memo1, PropList); // 取得 TMemo 的屬性
for i := 0 to Count -1 do begin
PropInfo := PropList[i];
PropName := PropInfo.Name; // 屬性名稱
// 動態取得物件屬性的質 Value := Memo1.?;
Value := GetPropValue(Memo1, PropInfo.Name);
// 印出屬性及其質
Memo1.Lines.Values[PropName] := VarToStr(Value);
end;
ShowMessage(Memo1.Hint);
end;
{
Name=Memo1
Tag=0
Left=27
Top=8
Width=565
Height=322
Cursor=0
Hint=test SetPropValue
HelpType=htContext
HelpContext=0
TabStop=True
Align=alNone
Alignment=taLeftJustify
Anchors=akLeft,akTop
BevelEdges=beLeft,beTop,beRight,beBottom
...
}
Delphi 使用 TypInfo 列出元件的屬性
uses
TypInfo;
在 From Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
PropList: PPropList;
Count, i: Integer;
PropInfo: PPropInfo;
begin
Memo1.Clear;
Count := GetPropList(Memo1, PropList); // 取得 TMemo 的屬性
for i := 0 to Count -1 do begin
PropInfo := PropList[i];
// 印出屬性及類型
Memo1.Lines.Add(PropInfo.Name + ': ' + PropInfo.PropType^^.Name);
end;
end;
{
Name: TComponentName
Tag: Integer
Left: Integer
Top: Integer
Width: Integer
Height: Integer
Cursor: TCursor
Hint: String
HelpType: THelpType
HelpKeyword: String
...
}
Delphi 使用 TApplicationEvents 來處理 Exception
在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
raise Exception.Create('Test Exception'); // 丟出例外
end;
在 ApplicationEvents Exception 事件中加入
procedure TForm1.ApplicationEvents1Exception(Sender: TObject; E: Exception);
begin
Memo1.Lines.Add(E.Message); // 將例外印在 Memo1 上
end;
指定 Delphi 的編譯條件
有 Conditional defines 可以設定 編譯條件,有多個條件時以分號分隔
在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
{$IFDEF DEBUG}
ShowMessage('DEBUG Conditional');
{$ELSE}
ShowMessage('Normal');
{$ENDIF}
end;
執行程式後會顯示 'Normal'
在 Conditional defines 入框中輸入 DEBUG 按 ok 後重 build
Project -> Build Project1
再次執行程式後會顯示 'DEBUG Conditional'
Delphi 使用 TActionList
設定屬性 ToolBar1.Images := ImageList1
設定屬性 ActionList1.Images := ImageList1
Double Click ActionList1 開啟 Editing 對話框
在 Editing 中按 New Standard Action...【Ctrl+Ins】 來開啟 Standard Action Classes 對話框
選擇所有 Edit 分類中的 class (TEditCut, TEditCopy, TEditPaste...) ,按 ok 加入這些 Action
在 ToolBar1 上按右鍵加入五個 TToolButton
在 ToolBar1 中
設定屬性 ToolButton1.Action := EditCut1
設定屬性 ToolButton2.Action := EditCopy1
設定屬性 ToolButton3.Action := EditPaste1
設定屬性 ToolButton4.Action := EditUndo1
設定屬性 ToolButton5.Action := EditDelete1
執行程式後 ToolBar1 上的 Button 就會依照目前 focus 的元件來運作(Copy, Paste...)
不可用的 Button 會變成灰色
Deiphi 使用 TObjectList 來管理物件
uses
Contnrs;
在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
list: TObjectList;
Strings1, Strings2: TStrings;
begin
list := TObjectList.Create(True); // Owns Objects
try
Strings1 := TStringList.Create;
list.Add(Strings1);
Strings1.Add('select * from a ...');
Strings2 := TStringList.Create;
list.Add(Strings2);
(list.Items[1] as TStrings).Add('select * from b ...');
finally
list.Free; // Free list ( Strings1, Strings2 ... )
end;
end;
使用 Delphi 來讀取 Registry 的資料
uses
Registry;
在 Form 上放一個 TMemo
在 FormCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
const
key = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run'; // Registry Key
var
i: Integer;
Registry: TRegistry;
Strings: TStrings;
Name: string;
begin
Memo1.Clear;
Strings := TStringList.Create;
Registry := TRegistry.Create;
try
Memo1.Lines.Add('<< HKEY_CURRENT_USER >>');
Registry.RootKey := HKEY_CURRENT_USER;
Registry.OpenKey(key, False);
Registry.GetValueNames(Strings);
for i := 0 to Strings.Count -1 do
begin
Name := Strings[i];
Memo1.Lines.Values[Name] := Registry.ReadString(Name);
end;
Registry.CloseKey;
Memo1.Lines.Add('<< HKEY_LOCAL_MACHINE >>');
Registry.RootKey := HKEY_LOCAL_MACHINE;
Registry.OpenKey(key, False);
Registry.GetValueNames(Strings);
for i := 0 to Strings.Count -1 do
begin
Name := Strings[i];
Memo1.Lines.Values[Name] := Registry.ReadString(Name);
end;
Registry.CloseKey;
finally
Registry.Free;
Strings.Free;
end;
end;
使用 log4delphi
http://log4delphi.sourceforge.net/
我目前下載的是 log4delphi-0.7-bin
解壓縮後 設定 Delphi 的 Library path
Tools -> Environment Options -> Library -> Library path
加入 解壓目錄中的 \log4delphi-0.7\bin
log4delphi 的設定檔有一個範本檔在 log4delphi-0.7\example\log4delphi.properties
建立一個新專案並存檔,複製 log4delphi.properties 到專案目錄之中
編輯專案中的 log4delphi.properties
# LEVEL 設為 DEBUG,使用 fileAppender 來記錄 log
log4delphi.rootLogger=DEBUG, fileAppender
# …
log4delphi.appender.fileAppender=TFileAppender
# …
# log file 設為程式執行目錄下的 app.log
log4delphi.appender.fileAppender.File=app.log
log4delphi.appender.fileAppender.AppDir=true
# …
# 將 layout 換成 TPatternLayout 來紀錄時間等資訊
#log4delphi.appender.fileAppender.layout=TSimpleLayout
log4delphi.appender.fileAppender.layout=TPatternLayout
log4delphi.appender.fileAppender.layout.Pattern=%d{dd mmm yyyy hh:nn:ss:zzz} [%5p] %m%n
# …
儲存 log4delphi.properties
在 Form Unit 的 implementation 區中加入
uses
TConfiguratorUnit, TLoggerUnit;
var
logger : TLogger;
// 在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
logger.debug('Debug message');
logger.info('Info message');
logger.warn('Warn message');
logger.error('Error message');
logger.fatal('Fatal message');
end;
initialization
TConfiguratorUnit.doPropertiesConfiguration('log4delphi.properties');
logger := TLogger.getInstance; // Create or Get Instance
finalization
TLogger.freeInstances; // Free
執行程式後,程式執行目錄下 log 會存入 app.log
Delphi 的 TStrings
在 Form 上放入 TValueListEditor, TMemo, TListBox, TComboBox, TRadioGroup, TCheckListBox, TListView, TQuery
uses
Printers;
在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
// ValueListEditor1.Strings 為 TStrings 子類別
with ValueListEditor1 do
begin
Values['TW'] := '臺灣'; // TW=臺灣
Values['CN'] := '中國'; // CN=中國
Strings.AddStrings(Printer.Printers); // 加列出印表機
// Printer.Printers 為 TStrings 子類別
Memo1.Lines := Strings; //
ListBox1.Items := Strings; //
RadioGroup1.Items := Strings; //
CheckListBox1.Items := Strings; //
ComboBox1.Items := Strings; //
ComboBox1.ItemIndex := 0;
Query1.SQL := Strings; // 測試用 Query1.SQL 也是 TStrings 子類別
with ListView1 do
begin
ViewStyle := vsReport;
Columns.Add.Caption := 'Caption';
Columns.Add.Caption := 'A';
Columns.Add.Caption := 'B';
with ListView1.Items.Add do
begin
Caption := '1';
SubItems := Strings; //
end;
end;
end;
end;
執行程式後除了 Query1 是不可見外,其它元件可以看到
Delphi 使用 DisableControls 加快對 DataSet 的操作
在 Form Create 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
DataSource1.DataSet := Table1;
DBGrid1.DataSource := DataSource1;
Table1.DatabaseName := 'BCDEMOS';
Table1.TableName := 'BDESDD.DB';
Table1.Active := True;
end;
在 Button1 Click 事件中加入
procedure TForm1.Button1Click(Sender: TObject);
var
n: string;
begin
ComboBox1.Items.Clear;
with Table1 do
begin
DisableControls; // 讓 DataSource 等元件停止運作,可加快 Next 的運作
try
First;
while not Eof do
begin
n := FieldByName('NAME').AsString;
// 將所有不重複 NAME 的資料 加入 ComboBox1 中
// 判斷長度大於 0 而且尚未加入 ComboBox1 中
if (Length(n) > 0) and (ComboBox1.Items.IndexOf(n) = -1) then
begin
ComboBox1.Items.Add(n);
end;
// ...
Next;
end;
finally
EnableControls; // 讓 DataSource 等元件運作
end;
end;
end;
Delphi Variant 和 VarArrayCreate
在 FormCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
v: Variant;
t: TVarType;
I: integer;
begin
with Memo1.Lines do
begin
Clear;
t := VarType(v); // 取得 Variant Type
if t = varEmpty then begin
Add('Empty Type'); // 初始為 Empty Type
end;
if VarIsEmpty(v) then begin
Add('Is Empty'); // 初始值為 Empty
end;
if VarIsClear(v) then begin
Add('Is Clear'); // Clear
end;
v := VarArrayCreate([0, 3], varVariant); // 建立陣列 array[0..3] of Variant
v[0] := 'Hello World';
v[1] := 1234.56;
v[2] := Now;
v[3] := Null; // 設為 Null
if VarIsArray(v) then begin
Add('Is Array, Length: ' +
IntToStr(VarArrayHighBound(v, 1) - VarArrayLowBound(v, 1)));
end;
for i := VarArrayLowBound(v, 1) to VarArrayHighBound(v, 1) do
begin
Add(Format('v[%d]: %s',[i, QuotedStr(VarToStr(v[i]))])); // 轉成字串
end;
if VarIsStr(v[0]) then begin
Add('v[0] Is String');
end;
if VarIsFloat(v[1]) then begin
Add('v[1] Is Float');
end;
if VarIsType(v[2], varDate) then begin
Add('v[2] Is Date');
end;
if VarIsNull(v[3]) then begin
Add('v[3] Is Null');
end;
VarClear(v); // 清為 Empty
if VarIsClear(v) and VarIsEmpty(v) then begin
Add('Is Clear and Empty'); // Clear
end;
end;
end;
Delphi 設定預設印表機
procedure SetDefaultPrinter(NewPrintName: string);
var
buffer: array[0..255] of Char;
name: string;
begin
name := NewPrintName;
if AnsiPos(',', name) = 0 then begin
name := name + ',';
end;
StrPCopy(buffer, name);
WriteProfileString('windows', 'device', buffer);
StrCopy(buffer, 'windows');
SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, Longint(@buffer));
end;
Delphi 處理大量資料時不讓 Form 凍結 Application.ProcessMessages
在 Form 上放一個 TMemo,一個 TButton
在 Button1 click 事件中加入
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
Memo1.Clear;
Application.ProcessMessages;
for i := 1 to 500 do
begin
Memo1.Lines.Add(IntToStr(i));
Sleep(10);
Application.ProcessMessages;
end;
end;
Delphi TStringList QuickSort 排序
在 implementation 區加入 function
// 字串反排
function DescCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := - AnsiCompareText(List[Index1], List[Index2]);
end;
// 在 FormCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
StringList: TStringList;
begin
StringList := TStringList.Create;
try
with StringList do
begin
Add('3');
Add('7');
Add('1');
Add('9');
Add('5');
end;
StringList.Sort; // 正排 會使用 QuickSort 來排序
Memo1.Lines := StringList; // 印到 Memo1
StringList.CustomSort(DescCompareStrings); // 使用反排 function
// CustomSort 會使用 QuickSort 來排序
Memo1.Lines.AddStrings(StringList); // 加到 Memo1
finally
StringList.Free;
end;
end;
{ Memo1
1
3
5
7
9
9
7
5
3
1
}
Delphi Projec Manager
Projec Manager 中會有一個專案群組(Project Group),可以在專案群組中加入多個專案
按 Mouse 右鍵選 Add New Project… 可加入新的專案
按 Mouse 右鍵選 Save Project Group 可儲存專案群組
按 Mouse 右鍵選 View Project Group Source 可自行編輯
#------------------------------------------------------------------------------
VERSION = BWS.01
#------------------------------------------------------------------------------
!ifndef ROOT
ROOT = $(MAKEDIR)\..
!endif
#------------------------------------------------------------------------------
MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$**
DCC = $(ROOT)\bin\dcc32.exe $**
BRCC = $(ROOT)\bin\brcc32.exe $**
#------------------------------------------------------------------------------
PROJECTS = Project1.exe Project2.exe
#------------------------------------------------------------------------------
default: $(PROJECTS)
#------------------------------------------------------------------------------
Project1.exe: Project1.dpr
$(DCC)
Project2.exe: Project2.dpr
$(DCC)
Delphi OLEDB 使用 ErrorCode 做錯誤處理
uses
ComObj, OleDB;
在元件屬性 ADOConnection1.ConnectionString 中指定資料庫,例如 DBDEMOS.udl
在元件屬性 ADODataSet1.Connection 指定為 ADOConnection1
在元件屬性 ADODataSet1.CommandText 寫入一個不存在的 QUERY TABLE,例如
select * from x
在 FormCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
try
ADODataSet1.Active := True;
except
on E: EOleException do begin
Memo1.Lines.Add('ErrorCode: ' + IntToHex(E.ErrorCode, 8));
Memo1.Lines.Add(E.Message);
case E.ErrorCode of
DB_E_NOTABLE: begin
// The specified table does not exist
Memo1.Lines.Add('Table 不存在');
end;
DB_E_INTEGRITYVIOLATION: begin
// A specified value violated the integrity constraints
// for a column or table
Memo1.Lines.Add('違反完整性約束,可能為資料重複');
Memo1.Lines.Add('或沒有外鍵所參考的值存在');
end;
DB_E_ERRORSINCOMMAND: begin
// The command contained one or more errors
Memo1.Lines.Add('SQL Command 發生一或多個錯誤');
end;
// 可加入其它的 ErrorCode 來做處理
else ;
end;
end;
end;
end;
{ Memo
ErrorCode: 80040E37
Microsoft Jet 資料庫引擎無法找到輸入資料表或查詢 'x'。請確定它是存在的而且名稱沒有拼錯。
Table 不存在
}
Delphi Midas 常數及資源字串檔
{ App Server }
SProviderNotExported = 'Provider not exported: %s';
{ DBClient }
SNoDataProvider = 'Missing data provider or data packet';
SInvalidDataPacket = 'Invalid data packet';
SRefreshError = 'Must apply updates before refreshing data';
...
{ MConnect }
SSocketReadError = 'Error reading from socket';
SInvalidProviderName = 'Provider name "%s" was not recognized by the server';
SBadVariantType = 'Unsupported variant type: %s';
...
Delphi OLEDB ErrorCode
ErrorCode 定義在 Unit OleDB 中
// Invalid accessor
//
DB_E_BADACCESSORHANDLE = HResult($80040E00);
...
// Unable to write with a read-only accessor
//
DB_E_READONLYACCESSOR = HResult($80040E02);
...
// Given values violate the database schema
//
DB_E_SCHEMAVIOLATION = HResult($80040E03);
...
// A literal value in the command could not be converted to the
// correct type due to a reason other than data overflow
//
DB_E_CANTCONVERTVALUE = HResult($80040E07);
...
// The command contained one or more errors
//
DB_E_ERRORSINCOMMAND = HResult($80040E14);
...
// A specified value violated the integrity constraints for a column or
// table
//
DB_E_INTEGRITYVIOLATION = HResult($80040E2F);
...
Delphi TXMLDocument
在 FormCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
with XMLDocument1.XML do
begin
Add('<?xml version="1.0" encoding="Big5"?>');
Add('<html lang="en">');
Add(' <head>');
Add(' <title>Extensible Markup Language (XML)</title>');
Add(' </head>');
Add(' <body>');
Add(' </body>');
Add('</html>');
end;
XMLDocument1.Active := True;
with XMLDocument1.DOMDocument do
begin
ShowMessage('tagName: ' + documentElement.tagName); // html
ShowMessage('Attribute lang: ' + documentElement.getAttribute('lang')); // en
with documentElement.firstChild.firstChild do
begin
ShowMessage('nodeName: ' + nodeName); // title
ShowMessage('nodeValue: ' + firstChild.nodeValue); // Extensible Markup Language (XML)
end;
end;
end;
Delphi 取得系統預設地區和語言
procedure TForm1.FormCreate(Sender: TObject);
var
DefaultLCID: Integer;
begin
DefaultLCID := SysLocale.DefaultLCID;
ShowMessage(Languages.NameFromLCID[IntToStr(DefaultLCID)]);
end;
Delphi 列出所有的語言
在 FormCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
lang: TLanguages;
i: Integer;
begin
lang := Languages;
with Memo1.Lines do
begin
Clear;
Add('Name'#9'Ext'#9'ID'#9'LocaleID');
for i := 0 to lang.Count -1 do
begin
Add(Format('%s'#9'%s'#9'%s'#9'%d', [
lang.Name[i],
lang.Ext[i],
lang.ID[i],
lang.LocaleID[i]
]));
end;
end;
end;
叫用 Delphi ADO 元件設什時期的 ConnectionString 屬性設定
uses
AdoConEd;
在 Form 上放一個 TADOConnection
在 FormCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
begin
AdoConEd.EditConnectionString(ADOConnection1);
end;
Delphi Bits 位元操作
在 FormCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
bit: TBits;
begin
with Memo1.Lines do
begin
Clear;
bit := TBits.Create;
try
bit.Size := 0;
bit.Bits[0] := True;
bit.Bits[1] := True;
bit.Bits[2] := False;
Add(IntToStr(bit.Size)); // 3
Add(IntToStr(bit.OpenBit)); // 2 first False
finally
bit.Free;
end;
end;
end;
Delphi 動態陣列
在 FormCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
a: array of String; // 動態字串陣列
i: Integer;
s: string;
begin
SetLength(a, 3); // a[0..2]
for i := Low(a) to High(a) do
begin
a[i] := IntToStr(i);
end;
s := '';
for i := Low(a) to High(a) do
begin
s := s + ',' + QuotedStr(a[i]);
end;
s[1] := '[';
s := s + ']';
with Memo1.Lines do
begin
Clear;
Add(s);
Add('Length: ' + IntToStr(Length(a)));
SetLength(a, 0); // Clear
Add('Length: ' + IntToStr(Length(a)));
end;
end;
使用 Delphi 的集合
在 FormCreate 事件中加入
procedure TForm1.FormCreate(Sender: TObject);
var
s: set of Byte;
begin
s := []; // 空集合
with Memo1.Lines do
begin
Clear;
if s = [] then
begin
Add('空集合');
end;
Include(s , 3); // add 3
s := s + [1] + [5, 7]; // [1,3,5,7]
if 5 in s then begin
Add('5 in [1,3,5,7]');
end;
Exclude(s, 5); // remove 5
if not (5 in s) then begin
Add('5 not in [1,3,7]');
end;
end;
end;
2009年5月28日
Delphi Debug Log
Delphi Menu 的 view -> Debug Windows -> Event Log (Ctrl + Alt + v)將顯示寫出的 Log
// 印出目前的時間到 Event Log 中
OutputDebugString(PChar( 'Now: ' + DateTimeToStr(Now) ));
Delphi Indy 取得設定網段中可用的 IP Address
procedure TForm1.FormCreate(Sender: TObject);
begin
IdNetworkCalculator1.NetworkAddress.AsString := '192.168.0.48';
IdNetworkCalculator1.NetworkMask.AsString := '255.255.255.240';
Memo1.Lines.Clear;
Memo1.Lines.Values['NetworkClass'] := IdNetworkCalculator1.NetworkClassAsString;
Memo1.Lines.AddStrings(IdNetworkCalculator1.ListIP);
end;
執行後會列出可用的 IP Address
Delphi Indy 網路偵測
procedure TForm1.IdIPWatch1StatusChanged(Sender: TObject);
begin
Memo1.Lines.Values['IsOnline'] := BooleanIdents[IdIPWatch1.IsOnline];
Memo1.Lines.Values['CurrentIP'] := IdIPWatch1.CurrentIP;
Memo1.Lines.Values['LocalIP'] := IdIPWatch1.LocalIP;
end;
執行程式後,當網路狀態改變時,就會觸發 OnStatusChanged 事件
Delphi Indy Base64 編解碼
// 編碼
IdEncoderMIME1.Encode('hello world!');
// 解碼
IdDecoderMIME1.DecodeString('aGVsbG8gd29ybGQh');
Delphi 用Indy元件取得UTF8編碼網頁資料
放入元件 Indy Clients -> IdHTTP,和一個memo元件
uses
IdURI;
在 FormCreate 事件中寫入
procedure TForm1.FormCreate(Sender: TObject);
var
url: string;
begin
url := 'http://www.wretch.cc/blog/blog.php?id=solnone&search='
+ TIdURI.ParamsEncode(UTF8Encode('Delphi 時間'));
Memo1.Lines.Text := UTF8Decode(IdHTTP1.Get(url));
end;
Delphi 的時間格式
var ShortDateFormat, LongTimeFormat, DateSeparator, TimeSeparator 等日期時間格式,來做為內定的日期時間格式。
程式中的 function DateTimeToStr, StrToDateTime 等轉換,若無指定,都將以 SysUtils 的內定日期時間格式來做轉換。
可以直接更改 SysUtils 中的 ShortDateFormat, LongTimeFormat, DateSeparator, TimeSeparator 等,就可以改掉內定的日期時間格式。
當作業系統的日期時間格式有更動時,內定的日期時間格式也會update。若不想變動內定日期時間格式,可以將在 unit Forms 中的 Application.UpdateFormatSettings 設定成 false,就不會再同步update 內定日期時間格式。
在 SysUtils 中有一個 record TFormatSettings,可以存入日期時間格式,程式中的 function DateTimeToStr, StrToDateTime 等轉換可以多傳入 TFormatSettings 參數來各自指定。
Delphi 使用 TStrings 的 Values
procedure TForm1.FormCreate(Sender: TObject);
var
s: TStrings;
begin
s := TStringList.Create;
with s do
begin
Clear;
Values['Sunday'] := '星期日';
Values['Monday'] := '星期一';
Values['Tuesday'] := '星期二';
ShowMessage(Text); // Sunday=星期日\r\nMonday=...
ShowMessage('Monday 是 ' + Values['Monday']); // Monday 是 星期一
Values['Sunday'] := ''; // 刪掉 Sunday
ShowMessage(Text); // Monday=星期一\r\n...
end;
s.Free;
end;
Delphi 字串分割
使用TStringList來分割字串,下面的範例是將字串 'a,b,c' 以 ',' 來分割
procedure TForm1.FormCreate(Sender: TObject);
var
s: TStrings;
begin
s := TStringList.Create;
try
s.Delimiter := ',';
s.DelimitedText :='a,b,c';
ShowMessage(s[0]);
ShowMessage(s[1]);
ShowMessage(s[2]);
finally
s.Free;
end;
end;
Delphi 使用資源檔
要使用資源檔,首先要用編輯器建立一個資源檔的腳本,附檔名為".rc"
內容為資源名稱、類別和檔案名稱,範例res.rc如下
READEME TXT "READEME.txt"
logo JPG "logo.jpg"
ok BMP "ok.bmp"
在${Delphi}\bin安裝目錄中有BRCC32.EXE這個程式,是用來將資源檔腳本中的檔案,
建立出一個資源檔,資源檔附檔名為".res"
在命令列中,先換目錄到資源檔腳本所在目錄,執行命令如下
Brcc32 res.rc
會產生res.res 資源檔
開啟 Delphi 在 unit 中加入資源檔 {$R 資源檔所在目錄\res.res}
在Form 中放入一個 Memo,在 FormCreate Event 中加入
procedure TForm1.FormCreate(Sender: TObject);
var
s: TResourceStream;
begin
s := TResourceStream.Create(HInstance, 'READEME','TXT');
try
Memo1.Lines.LoadFromStream(s);
finally
s.Free;
end;
end;
執行程式將會載入資源檔中的READEME.TXT到Memo中
Delphi 以類別名稱來建立物件
若想用父類別來操作,而不想 use 各子類別,則可以類別名稱來動態建立子類別物件
在 unit Classes 中,有RegisterClass, GetClass, FindClass 和 UnRegisterClass
先使用 RegisterClass 註冊所需動態建立的類別
然後才能使用 GetClass 或 FindClass 以類別名稱來找出註冊過的類別
再轉型為所需的父類別來建立並使用物件
若不再需要它,則可以使用 UnRegisterClass 來取消註冊
procedure TForm1.FormCreate(Sender: TObject);
var
PClass: TPersistentClass;
Strings: TStrings;
begin
PClass := FindClass('TStringList');
Strings := PClass.Create as TStrings;
try
Strings.Add('Hi');
finally
Strings.Free;
end;
end;
initialization
RegisterClass(TStringList);
finalization
UnRegisterClass(TStringList);
Delphi Unit 的結構
Delphi Unit 最簡單的結構如下
unit{ 單元開頭 } Unit1; interface implementation end{ 單元結尾 }. |
主要分為二節區,interface和implementation
- interface 區為對外公開的宣告
- implementation 區為不對外開放的實作 code 以及interface 區的實作 code
- initialization 區為此 unit 初始化時執行的 code
- finalization 區為程式結束時執行的 code,主要目的是釋放 initialization 區所建立的資源
unit{ 單元開頭 } Unit1; |
在 interface和implementation 區中,可以有一個 uses 來使用其它 unit 的資源,以 interface 中的 uses 為宣告中所要用到的資源,implementation 中的 uses 則是在實作時所要用到的資源,且未出現在 interface 中的 uses內。
unit Unit1; interface uses implementation uses initialization finalization end. |
在 interface和implementation 區中,在 uses 之後,可以有多個 const, resourcestring, type, var
unit Unit1; interface uses implementation uses const { 常數 } resourcestring { 資源字串 } type { 定義 } var { 變數 } initialization finalization end. |
在 interface區中, 宣告對外公開的 procedure 和 function
在implementation 區中,實作procedure 和 function
unit Unit1; interface uses implementation uses const { 常數 } resourcestring { 資源字串 } type { 定義 } var { 變數 } function GetPI_SQUARE: Double; initialization finalization end. |