Subscribe

RSS Feed (xml)

Powered By

Skin Design:
Free Blogger Skins

Powered by Blogger

星期五, 9月 28, 2007

Thread實作排序法(泡沫、選擇、快速排序法)


首先新增一個Thread並命名為TSortThread,接著另存新檔為SortThds.pas,並加入以下程式碼

unit SortThds;

interface

uses
Classes, Graphics, ExtCtrls;

type
{ TSortThread }
PSortArray = ^TSortArray;
TSortArray = array[0..MaxInt div SizeOf(Integer) - 1] of Integer;

TSortThread = class(TThread)
private
FBox: TPaintBox;
FSortArray: PSortArray;
FSize: Integer;
FA, FB, FI, FJ: Integer;
procedure DoVisualSwap;
{ Private declarations }
protected
procedure Execute; override; //Thread自動會產生
procedure VisualSwap(A, B, I, J: Integer);
procedure Sort(var A: array of Integer); virtual; abstract;
public
constructor Create(Box: TPaintBox; var SortArray: array of Integer);
end;

//{ TBubbleSort }類型
TBubbleSort = class(TSortThread)
protected
procedure Sort(var A: array of Integer); override;
end;

//{ TSelectionSort }類型
TSelectionSort = class(TSortThread)
protected
procedure Sort(var A: array of Integer); override;
end;

//{ TQuickSort }類型
TQuickSort = class(TSortThread)
protected
procedure Sort(var A: array of Integer); override;
end;

procedure PaintLine(Canvas: TCanvas; I, Len: Integer);

implementation

//畫線
procedure PaintLine(Canvas: TCanvas; I, Len: Integer);
begin
Canvas.PolyLine([Point(0, I * 2 + 1), Point(Len, I * 2 + 1)]);
end;

{ TSortThread }
constructor TSortThread.Create(Box: TPaintBox; var SortArray: array of Integer);
begin
FBox := Box;
FSortArray := @SortArray;
FSize := High(SortArray) - Low(SortArray) + 1;
FreeOnTerminate := True; //不知道做什麼用
inherited Create(False);
end;

procedure TSortThread.DoVisualSwap;
begin
FBox.Canvas.Pen.Color := clBtnFace; //系統默認顏色
PaintLine(FBox.Canvas, FI, FA); //畫線
PaintLine(FBox.Canvas, FJ, FB); //畫線
FBox.Canvas.Pen.Color := clRed; //紅色
PaintLine(FBox.Canvas, FI, FB); //畫線
PaintLine(FBox.Canvas, FJ, FA); //畫線
end;

procedure TSortThread.VisualSwap(A, B, I, J: Integer);
begin
FA := A;
FB := B;
FI := I;
FJ := J;
Synchronize(DoVisualSwap); //同步執行DoVisualSwap
end;

//泡沫排序法程序
procedure TBubbleSort.Sort(var A: array of Integer);
var
I, J, T: Integer;
begin
for I := High(A) downto Low(A) do
for J := Low(A) to High(A) - 1 do
if A[J] > A[J + 1] then
begin
VisualSwap(A[J], A[J + 1], J, J + 1); //圖案交換
T := A[J];
A[J] := A[J + 1];
A[J + 1] := T;
if Terminated then Exit;
end;
end;

//選擇排序法程序
procedure TSelectionSort.Sort(var A: array of Integer);
var
I, J, T: Integer;
begin
for I := Low(A) to High(A) - 1 do
for J := High(A) downto I + 1 do
if A[I] > A[J] then
begin
VisualSwap(A[I], A[J], I, J); //圖案交換
T := A[I];
A[I] := A[J];
A[J] := T;
if Terminated then Exit;
end;
end;

//快速排序法程序
procedure TQuickSort.Sort(var A: array of Integer);
procedure QuickSort(var A: array of Integer; iLo, iHi: Integer);
var
Lo, Hi, Mid, T: Integer;
begin
Lo := iLo;
Hi := iHi;
Mid := A[(Lo + Hi) div 2];
repeat
while A[Lo] < Mid do Inc(Lo);
while A[Hi] > Mid do Dec(Hi);
if Lo <= Hi then
begin
VisualSwap(A[Lo], A[Hi], Lo, Hi); //圖案交換
T := A[Lo];
A[Lo] := A[Hi];
A[Hi] := T;
Inc(Lo);
Dec(Hi);
end;
until Lo > Hi;
if Hi > iLo then QuickSort(A, iLo, Hi);
if Lo < iHi then QuickSort(A, Lo, iHi);
if Terminated then Exit;
end;
begin
QuickSort(A, Low(A), High(A));
end;

{ The Execute method is called when the thread starts }
procedure TSortThread.Execute;
begin
Sort(Slice(FSortArray^, FSize));
end;

end.


然後再主視窗程式加入3個TLabel、1個TButton、3個TPaintBox。
事件:
3個TPaintBox事件OnPaint皆點兩下加入,還有TButton點兩下加入。
最後貼上程式碼:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Button1: TButton;
PaintBox1: TPaintBox;
PaintBox2: TPaintBox;
PaintBox3: TPaintBox;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
procedure PaintBox2Paint(Sender: TObject);
procedure PaintBox3Paint(Sender: TObject);
private
ThreadsRunning: Integer;
procedure RandomizeArrays;
procedure ThreadDone(Sender: TObject);
{ Private declarations }
public
procedure PaintArray(Box: TPaintBox; const A: array of Integer);
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses SortThds;

{$R *.dfm}
type
PSortArray = ^TSortArray;
TSortArray = array[0..114] of Integer;

var
ArraysRandom: Boolean;
BubbleSortArray, SelectionSortArray, QuickSortArray: TSortArray;

{ TThreadSortForm }
procedure TForm1.PaintArray(Box: TPaintBox; const A: array of Integer);
var
I: Integer;
begin
Box.Canvas.Pen.Color := clRed; //決定畫筆的線條顏色型態
for I := Low(A) to High(A) do PaintLine(Box.Canvas, I, A[I]);//畫從第一條線長度到最後
end;

procedure TForm1.RandomizeArrays;
var
I: Integer;
begin
if not ArraysRandom then //是否可Random
begin
Randomize;
for I := Low(BubbleSortArray) to High(BubbleSortArray) do //0~114
begin
BubbleSortArray[I] := Random(170); //0~170之間的亂數
end;
SelectionSortArray := BubbleSortArray; //與泡沫排序Array相同
QuickSortArray := BubbleSortArray; //與泡沫排序Array相同
ArraysRandom := True; //Random好了
Repaint;
end;
end;

procedure TForm1.ThreadDone(Sender: TObject);
begin
Dec(ThreadsRunning); //減到為0又可以可以重跑
if ThreadsRunning = 0 then
begin
Button1.Enabled := True; //Thread跑完後
ArraysRandom := False; //又可以重開始Random
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
RandomizeArrays;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
RandomizeArrays;
ThreadsRunning := 3;//3個Thread會同時跑

TBubbleSort.Create(PaintBox1, BubbleSortArray).OnTerminate := ThreadDone;//當執行序結束時執行ThreadDone
TSelectionSort.Create(PaintBox2, SelectionSortArray).OnTerminate := ThreadDone;
TQuickSort.Create(PaintBox3, QuickSortArray).OnTerminate := ThreadDone;

Button1.Enabled := False; //禁再重覆按Button
end;

//泡沫排序畫圖
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
PaintArray(PaintBox1, BubbleSortArray);
end;

//選擇排序畫圖
procedure TForm1.PaintBox2Paint(Sender: TObject);
begin
PaintArray(PaintBox2, SelectionSortArray);
end;

//快速排序畫圖
procedure TForm1.PaintBox3Paint(Sender: TObject);
begin
PaintArray(PaintBox3, QuickSortArray);
end;

end.

星期三, 9月 26, 2007

RAR壓縮及解壓縮




首先要加入OBRARCompress的元件,然後新增1個視窗form、1個TProgressBar,並加入PageControl1及新增兩個Page:

TabSheet1有
3個TLabel、2個TEdit(密碼的TEdit屬性PasswordChar=*)、4個TButton、1個TMemo、1個TOpenDiolag及TOBRARCompress。

TabSheet2有
3個TLabel、3個TEdit(密碼的TEdit屬性PasswordChar=*、解壓縮至的TEdit屬性Text=C:\)、2個TButton。

事件:
除了所有按鈕皆點兩下加入外,TOBRARCompress事件OnCompressing也要加入。



unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, OBRARCompress;

type
TForm1 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
ProgressBar1: TProgressBar;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Button5: TButton;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Button6: TButton;
OpenDialog1: TOpenDialog;
OBRARCompress1: TOBRARCompress;
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure OBRARCompress1Compressing(Sender: TObject;
Progress: Integer);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
procedure UpdateControlsStatus1(Enabled : Boolean);
procedure UpdateControlsStatus2(Enabled : Boolean);
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
procedure TForm1.UpdateControlsStatus1(Enabled: Boolean);
begin
Edit1.Enabled := Enabled;
Edit2.Enabled := Enabled;
Memo1.Enabled := Enabled;
Button1.Enabled := Enabled;
Button2.Enabled := Enabled;
Button3.Enabled := Enabled;
Button4.Enabled := Enabled;
end;

procedure TForm1.UpdateControlsStatus2(Enabled: Boolean);
begin
Edit3.Enabled := Enabled;
Edit4.Enabled := Enabled;
Edit5.Enabled := Enabled;
Button5.Enabled := Enabled;
Button6.Enabled := Enabled;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
OpenDialog1.Filter := 'RAR文件|*.rar';
if not OpenDialog1.Execute then
Exit;
Edit1.Text := OpenDialog1.FileName;
if Pos('.rar',Edit1.Text)>0 then
Exit;
Edit1.Text := Edit1.Text + '.rar';
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
Memo1.Lines.Clear;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
OpenDialog1.Filter := '所有文件|*.*';
if not OpenDialog1.Execute then
Exit;
Memo1.Lines.Add(OpenDialog1.FileName);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
//如果為TRUE的,而文件路徑又太長的時候,Memo會自動換行,
//會導致下面OBRARCompress1.SourceFiles.Assign得到的文件名不正確
Memo1.WordWrap:=false;


UpdateControlsStatus1(False);
Screen.Cursor := crHourGlass;

//動態創建OBRARCompress控件
try
//OBRARCompress1.OnCompressing:=OBCompressing;
OBRARCompress1.SourceFiles.Assign(Memo1.Lines);
OBRARCompress1.RARFileName := Edit1.Text;
OBRARCompress1.Password := Edit2.Text;
if OBRARCompress1.Compress then
ShowMessage('壓縮成功啦 !')
else
ShowMessage('壓縮失敗啦 !');
finally
UpdateControlsStatus1(True);
ProgressBar1.Position := 0;
Screen.Cursor := crDefault;
end;
end;

procedure TForm1.OBRARCompress1Compressing(Sender: TObject;
Progress: Integer);
begin
ProgressBar1.Position := Progress;
Application.ProcessMessages;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
OpenDialog1.Filter := 'RAR文件|*.rar';
if not OpenDialog1.Execute then
Exit;
Edit3.Text := OpenDialog1.FileName;
if Pos('.rar',Edit3.Text)>0 then
Exit;
Edit3.Text := Edit3.Text + '.rar';
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
OBRARCompress1.RARFileName := Edit3.Text;
if not DirectoryExists(Edit4.Text) then
CreateDir(Edit4.Text);
OBRARCompress1.UnPath:=Edit4.text;
OBRARCompress1.Password := Edit5.Text;
UpdateControlsStatus2(False);
Screen.Cursor := crHourGlass;
try
try
if OBRARCompress1.UNCompress then
ShowMessage('解壓縮成功啦 !')
else
ShowMessage('解壓縮失敗啦 !');
except
ShowMessage('解壓縮出現了問題 !');
end;
finally
UpdateControlsStatus2(True);
ProgressBar1.Position := 0;
Screen.Cursor := crDefault;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
PageControl1.TabIndex :=0;
end;

end.

zLib.dll、UnzLib.dll、OBRARCompress.dcu 皆要放在同一目錄喔。

星期五, 9月 21, 2007

TIdTCPServer & Client 傳檔工具




Server程式
須要新增1個按鈕TButton、2個TLabel、1個TLsitBox屬性PopupMenu=PopupMenu1及屬性MultiSelect=true、1個TOpenDialog、1個TPopupMenu、1個TIdTCPServer屬性Bindings=:9999及屬性DefaltPort=9999,並加入OnExecute


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, StdCtrls, IdBaseComponent, IdComponent, IdTCPServer,
IdThreadMgr, IdThreadMgrDefault;

type
TForm1 = class(TForm)
IdTCPServer1: TIdTCPServer;
ListBox1: TListBox;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
OpenDialog1: TOpenDialog;
PopupMenu1: TPopupMenu;
N1: TMenuItem;
N2: TMenuItem;
procedure Button1Click(Sender: TObject);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
procedure FormCreate(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure N2Click(Sender: TObject);
private
FConnectionCount: Integer;
procedure IncrConnectionCount;
procedure DecrConnectionCount;
{ Private declarations }
public
{ Public declarations }
end;

function SendString(Sender: Tobject; iMsg: string): Boolean;
function SendFile(Sender: Tobject; iFileName: string): Boolean;

var
Form1: TForm1;
AppPath: string;

implementation

{$R *.dfm}

//傳送訊息出去
function SendString(Sender: Tobject; iMsg: string): Boolean;
var
AStream: TStringStream;
AThread: TIdPeerThread;
begin
AThread := (sender as TIdPeerThread);
AStream := TStringStream.Create(iMsg);
try
AThread.Connection.OpenWriteBuffer;
AThread.Connection.WriteStream(AStream);
AThread.Connection.CloseWriteBuffer;
result := true;
finally
AStream.Free;
end;
end;

//傳送檔案出去
function SendFile(Sender: Tobject; iFileName: string): Boolean;
var
FStream: TFileStream;
AThread: TIdPeerThread;
i: integer;
itmpFileName: string;
begin
//========依client 所傳的檔名取出server 端的完整路徑檔名

for i := 0 to Form1.Listbox1.Count - 1 do
if iFileName = UpperCase(ExtractFileName(Form1.ListBox1.Items.Strings[i])) then
itmpFileName := Form1.ListBox1.Items.Strings[i];

//=============================================
AThread := (sender as TIdPeerThread);

if itmpFileName = '' then
begin
AThread.Connection.WriteLn('Filename not fount!');
result:=False;
exit;
end;
FStream := TfileStream.Create(itmpFileName, fmOpenRead);
try
AThread.Connection.OpenWriteBuffer;
FStream.Seek(0, soFromBeginning);
AThread.Connection.WriteStream(FStream, False, False, FStream.Size);
AThread.Connection.CloseWriteBuffer;
result := true;
finally
FStream.Free;
end;
end;

procedure TForm1.IncrConnectionCount;
begin
Inc(FConnectionCount);
Label2.Caption := '連線數:' + IntToStr(FConnectionCount); //顯示連線數
end;

procedure TForm1.DecrConnectionCount;
begin
Dec(FConnectionCount);
Label2.Caption := '連線數:' + IntToStr(FConnectionCount); //顯示連線數
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
OpenDialog1.Execute; //開啟檔案盒
ListBox1.Items.AddStrings(OpenDialog1.Files); //將所選檔案累加至ListBox1
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
SRequest: string;
//SOutline: string;
//AStream: TStringStream;
//FStream: TFileStream;
//i: integer;
begin

AThread.Synchronize(IncrConnectionCount);

AThread.Connection.WriteLn('Welcome to Auto Update Server');
try
SRequest := UpperCase(AThread.Connection.ReadLn);

//檔案資訊
if SRequest = 'GETFILEINFO' then
SendString(AThread, ListBox1.Items.Text); //傳給Client檔名

//傳送檔案
if SRequest = 'GETFILE' then //傳檔需求
begin
AThread.Connection.WriteLn('FILENAME?'); //尋問要取那一個檔
SRequest := UpperCase(AThread.Connection.ReadLn);
SendFile(AThread, SRequest);
end;

finally
AThread.Connection.Disconnect;
AThread.Synchronize(DecrConnectionCount);
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
IdTCPServer1.Active := True; //啟動Server
AppPath := GetCurrentDir; //先取得程式執行目錄,並儲存
OpenDialog1.Options := [ofAllowMultiSelect]; //檔案對話框多選

//載入下載檔案列表
if FileExists(AppPath + '\UpdateFiles.txt') then
listbox1.Items.LoadFromFile(AppPath + '\UpdateFiles.txt');
end;

procedure TForm1.N1Click(Sender: TObject);
begin
ListBox1.SelectAll; //全選
end;

procedure TForm1.N2Click(Sender: TObject);
var
i: integer;
begin
for i := ListBox1.Count - 1 downto 0 do //由最後一筆開始刪index才不會出錯
if ListBox1.Selected[i] = True then
ListBox1.Items.Delete(i);
end;
end.


Client程式
5個TLabel、2個TPanel、3個TEdit(都有初始文字;請參考圖)、1個TButton、1個TListBox及1個TIdTCPClient

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
Panel1: TPanel;
Label1: TLabel;
Label2: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
ListBox1: TListBox;
Panel2: TPanel;
Label3: TLabel;
Edit3: TEdit;
Label4: TLabel;
Label5: TLabel;
IdTCPClient1: TIdTCPClient;
procedure Button1Click(Sender: TObject);
private
procedure GetFiles(SaveFilePath: string; iFileName: string);
function GetFileName(): TStrings;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
//-----------讀取檔案列表-------------
function TForm1.GetFileName(): TStrings;
var
AStream: TStringStream;
SResponse: string;
begin
AStream := TStringStream.Create('');
result := TStringList.Create;
try
IdTCPClient1.Connect();
SResponse := UpperCase(IdTCPClient1.ReadLn); //讀取伺服器回應
if Pos('WELCOME', SResponse) = 0 then exit; //若無回應則離開


IdTCPClient1.WriteLn('GETFILEINFO'); //讀取檔案資訊
IdTCPClient1.ReadStream(AStream, -1, True);
AStream.Seek(0, soFromBeginning);
result.LoadFromStream(AStream);
finally
AStream.Free;
IdTCPClient1.Disconnect;
end;
end;

procedure TForm1.GetFiles(SaveFilePath: string; iFileName: string);
var
FStream: TFileStream;
SResponse: string;
begin
try
IdTCPClient1.Connect();
while IdTCPClient1.Connected do
begin
SResponse := UpperCase(IdTCPClient1.ReadLn); //讀取伺服器回應
if Pos('WELCOME', SResponse) = 0 then
break; //若無回應則離開

IdTCPClient1.WriteLn('GETFILE');
SResponse := UpperCase(IdTCPClient1.ReadLn); //讀取伺服器回應
IdTCPClient1.WriteLn(iFileName);
FStream := TFileStream.Create(SaveFilePath + '\' + iFileName, fmCreate);
try
FStream.Seek(0, soFromBeginning);
IdTCPClient1.ReadStream(FStream, -1, True);
finally
FStream.Free;
end;
end;
finally
IdTCPClient1.Disconnect;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
tmpFileName: string;
i: Integer;
begin
IdTCPClient1.Host := Edit1.Text;
IdTCPClient1.Port := strtoint(Edit2.Text);
listbox1.Items := GetFileName; //取得檔名
label5.Caption :='傳檔中,請稍候....';
for i := 0 to listbox1.Count - 1 do
begin
tmpFileName := ExtractFileName(Listbox1.Items.Strings[i]);
GetFiles(IncludeTrailingBackslash(Edit3.Text), tmpFileName);
end;
label5.Caption :='傳檔完成....';
end;
end.

星期四, 9月 20, 2007

簡單的MP3、WAV、MID播放器


新增5個TButton按鈕,Caption分別為:
&Open
>

&Back
&Next
再新增1個TProgressBar,1個TListBox,1個TMediaPlayer且屬性Visible = False。
1個TOpenDialog且屬性Filter = 所有音樂格式*.wav;*.mp3;*.mid
1個TTimer

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, MPlayer, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
ProgressBar1: TProgressBar;
ListBox1: TListBox;
MediaPlayer1: TMediaPlayer;
Timer1: TTimer;
OpenDialog1: TOpenDialog;
procedure ListBox1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
procedure PlayAudio;
procedure NextTrack;
procedure BackTrack;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
ss: String;
PlayIndex: integer = 0;

implementation

{$R *.dfm}
procedure TForm1.PlayAudio;
begin
try
if ListBox1.Items.Count > 0 then //歌大於1首才可
begin
if ListBox1.ItemIndex = -1 then //未選擇就0 指第一首
ListBox1.ItemIndex := 0;
ss := ListBox1.Items.Strings[ListBox1.ItemIndex]; //取到檔名
MediaPlayer1.FileName := ss;
MediaPlayer1.Open;
MediaPlayer1.Play;
end;
except;
end;
end;

procedure TForm1.NextTrack;
begin
try
PlayIndex := ListBox1.ItemIndex;
Inc(PlayIndex); //加1
if PlayIndex = ListBox1.Items.Count then
PlayIndex := 0; //跳到第一首
ListBox1.ItemIndex := PlayIndex;

ss := ListBox1.Items.Strings[PlayIndex];
MediaPlayer1.FileName := ss;
MediaPlayer1.Open;
if MediaPlayer1.FileName = '' then
PlayAudio
else
MediaPlayer1.Resume;
except;
end;
end;

procedure TForm1.BackTrack;
begin
try
PlayIndex := ListBox1.ItemIndex;
Dec(PlayIndex); //減1
if PlayIndex < filename =" ''" filename =" ''" caption =" '">' then
begin
MediaPlayer1.Resume;
button2.caption:='';
end else
begin
MediaPlayer1.Pause;
button2.caption:='>';
end;
except;
end;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
try
BackTrack
except
end;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
try
NextTrack
except
end;
end;

procedure TForm1.ListBox1Click(Sender: TObject); //連點兩下
begin
PlayAudio;
button2.caption:='';
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if MediaPlayer1.FileName <> '' then
try
ProgressBar1.Max := MediaPlayer1.Length; //MediaPlayer1.Length音樂長度
ProgressBar1.Position := MediaPlayer1.Position; //MediaPlayer1.Position播放位置
ProgressBar1.Update;
MediaPlayer1.Update;
if MediaPlayer1.Position >= MediaPlayer1.Length then
NextTrack;
except;
end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
MediaPlayer1.stop; //停止播放
MediaPlayer1.FileName := ''; //名稱為''是為了跑PlayAudio
button2.caption:='>'; //按鈕圖示變
ProgressBar1.Position := 0; //手控狀態bar
end;

end.

將字串有空白的地方皆去除掉

tmpString := StringReplace(tmpString,' ','',[rfReplaceAll]);

字串基本處理

1CompareStr 比較兩字串的大小(大小寫視為不同),傳回第一個不相同字元 ASCII 碼的差,若字串完全相同,則傳回 0 (字串的編號從 1 開始)。

function CompareStr(const S1, S2 : string) : Integer;

傳回結果:

當 S1>S2 傳回大於 0 的整數

當 S1<S2 傳回小於 0 的整數

當 S1=S2 傳回 0

範例:

S1:='Delphi 6.0';

S2:='delphi 6.0';

if CompareStr(S1,S2)<>0 then

showMessage('大小寫被視為不同的!');

2CompareText比較兩字串的大小(大小寫視為相同),傳回第一個不相同字元 ASCII 碼的差

function CompareText(const S1, S2:string) : Integer;

傳回結果:

當 S1>S2 傳回大於 0 的整數

當 S1<S2 傳回小於 0 的整數

當 S1=S2 傳回 0

範例:

S1:='Delphi';

S2:='delphi';

ResultFlag:=CompareText(S1,S2);

if ResultFlag <>

ShowMessage('Delphi <>

else if ResultFlag > 0 then

ShowMessage('Delphi > delphi')

else

ShowMessage('Delphi = delphi');

{Delphi = delphi}

3Length傳回字串 S 的長度

function Length(S) : Integer;

範例:

S:='Delphi 6.0 讚 '; //中文算兩個Bytes,長度包含空白

ShowMessage(IntToStr(Length(S)));

{14}

4Concat傳回字串相加的結果。使用字串相加(+)運算子,亦有相同的效果,且執行速度較快

function Concat(s1 [, s2, ..., sn ] : string) : string;

範例:

S1:='今天';

S2:='下雨';

ShowMessage(Concat(S1, S2));

{今天下雨}

5Insert將 Source 字串插入 S 字串的第 count 個字元位置(字串的編號從 1 開始)

procedure Insert(Source : string; var S : string; Index : Integer);

範例:

S1:='I Love you!';

S2:=' don''t';

insert(S2, S1, 2);

showmessage(S1);

{I don't Love you!}

6Copy傳回 S 字串的第 Index 字元起,拷貝 Count 個字元(字串的編號從 1 開始)

function Copy(S; Index, Count:Integer) : string;

範例:

S:='Delphi 2006 is good??!';

S:=Copy(S, 1, 11);

ShowMessage(S);

{Delphi 2006}

7Delete將 S 字串從第 Index 字元開始,刪除 Count 個字元(字串的編號從 1 開始)

procedure Delete(var S : string; Index, Count : Integer);

範例:

S:='Delphi is good??!';

Delete(S, 15, 2);

ShowMessage(S);

{Delphi is good!}

8Pos傳回 Substr 字串於 S 字串的開始位置(字串的編號從 1 開始)

function Pos(Substr : string; S : string) : Integer;

範例:

S:=' Delphi is good ';

while Pos(' ', S)>0 do

begin

i:=Pos(' ', S);

showmessage(inttostr(i));

S[i]:='_';

end;

{1, 8, 11, 16, 17}

9Trim清除字串前後的空白

function Trim(const S : string) : string;

範例:

S1:=' Delphi 6.0 ';

ShowMessage(Trim(S1));

{'Delphi 6.0'}

10TrimLeft清除字串左邊的空白

function TrimLeft(const S : string) : string;

範例:
S1:=' Delphi 6.0 ';

ShowMessage(TrimLeft(S1));

{'Delphi 6.0 '}

11TrimRight 清除字串右邊的空白

function TrimRight(const S : string) : string;

範例:

S1:=' Delphi 6.0 ';

ShowMessage(TrimRight(S1));

{' Delphi 6.0'}

傳回及設定檔案的日期及時間


procedure TForm1.Button1Click(Sender: TObject);
begin
// FileAge (傳回檔案的日期時間)
// function FileAge(const FileName : string) : Integer;
ShowMessage(DateTimeToStr(FileDateToDateTime(FileAge('c:\test.dat'))));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
FileHandle : Integer;
begin
// FileSetDate (設定檔案的日期及時間)
// function FileSetDate(Handle : Integer; Age : Integer) : Integer;
FileHandle := FileOpen('c:\test.dat', fmOpenReadWrite);
if FileHandle = -1 then
ShowMessage('開啟檔案失敗')
else begin
if FileSetDate(FileHandle, FileGetDate(FileHandle))=0 then
ShowMessage('檔案日期時間設定成功')
else
ShowMessage('檔案日期時間設定失敗')
end;
FileClose(FileHandle);
end;

更改檔名及虛擬更改檔名


procedure TForm1.Button1Click(Sender: TObject);
begin
// ChangeFileExt (改變指定檔案的副檔名,只傳回新檔名並未真正的改變)
// function ChangeFileExt(const FileName, Extension : string) : string;
ShowMessage(ChangeFileExt('c:\test.txt','.bak'));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
// RenameFile (更改檔名)
// function RenameFile(const OldName, NewName : string) : Boolean;
if FileExists('c:\test.txt') then //判斷檔整是否存在
if RenameFile('c:\test.txt','c:\test.dat') then
ShowMessage('更名成功')
else
ShowMessage('更名失敗')
else
ShowMessage('指定檔案不存在');
end;

星期二, 9月 18, 2007

滑鼠鎖定

今天來跟大家分享鎖定滑鼠
其實只要一點點小步驟就可以了,最後程式按ESC就可以離開。
放一個TTimer控件到表單上
屬性:
Enabled:True
Interval:200
事件:
Form的KeyPress
Timer點兩下
程式碼加入:

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if key=#27 then
Application.Terminate;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
setcursorpos(300,300);
end;

Ping工具



視窗上有
2個TLabel、1個TEdit、1個TMemo、1個TButton、1個LMDSpinEdit1,然後再放一個IdIcmpClient元件(在IndyClient那裡)
然後在Button的onClick點兩下,及IdIcmpClient元件上點兩下,最後加入下列程式碼:

procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
IdIcmpClient1.OnReply := IdIcmpClient1Reply; //設置回應屬性
IdIcmpClient1.ReceiveTimeout := 1000; //設置連線時間
Button1.Enabled := False; //禁止按鈕
try
IdIcmpClient1.Host := Edit1.Text; //輸入Edit1的Host
for i := 1 to LMDSpinEdit1.Value do begin //開始連線次數迴圈
IdIcmpClient1.Ping; //開始連線
Application.ProcessMessages; //發送訊息
//sleep(1000);//可加入暫停一秒
end;
finally
Button1.Enabled := True; //恢復按鈕
end;
end;

procedure TForm1.IdIcmpClient1Reply(ASender: TComponent;
const AReplyStatus: TReplyStatus);
var
sTime: string;
begin
// TODO: check for error on ping reply (ReplyStatus.MsgType?)
if (AReplyStatus.MsRoundTripTime = 0) then
sTime := '<1'
else
sTime := '=';

Memo1.Lines.Add(Format('IP位址=%s bytes=%d ICMP_seq=%d TTL=%d 存在時間%s%d豪秒',
[AReplyStatus.FromIpAddress, //IP位址
AReplyStatus.BytesReceived, //Bytes
AReplyStatus.SequenceId,
AReplyStatus.TimeToLive, //TTL
sTime,
AReplyStatus.MsRoundTripTime])); //時間
end;

簡單寫本機Port掃描器


首先可能要增加之前的元件
[ components ] --> [ install packages ] --> [ add ] --> choose C:\Program Files\Borlad\BDS\4.0\Bin\dclsockets100.bpl
接著在Internet就會多個TServerSocket。
然後開始設計視窗:
2個Label、2個Edit、1個Button、1個Memo、1個ProgressBar、1個TServerSocket、1個StatusBar
並將TServerSocket的Active屬性變成true。
最後在Button的onClick事件加入下列程式碼:

procedure TForm1.Button1Click(Sender: TObject);
var
a:integer; //a為整數
begin
Button1.Enabled:=false;
StatusBar1.SimpleText:='掃描中…請稍等…';//當按鈕按下時狀態列出現掃瞄中字樣
ProgressBar1.max:=strtoint(Edit2.Text)-strtoint(Edit1.Text);
ProgressBar1.Position:=0;//初始狀態是0
Memo1.Clear; //當按鈕按下時Memo1的內容清空
for a:=strtoint(Edit1.Text) to strtoint(Edit2.Text) do
begin
ProgressBar1.Position:=a-strtoint(Edit1.Text);
ServerSocket1.Close;
ServerSocket1.Port:=a;//Port為整數a
try
ServerSocket1.Open;
except
Memo1.Lines.Add('Port '+inttostr(a)+'是打開的');//當Port出現重複時 Memo1會出現提示end;
StatusBar1.SimpleText:='正在掃描Port'+inttostr(a);//狀態列會出現正在掃描哪個Port
end;
end;
StatusBar1.SimpleText:='掃描完畢';//掃描完之後出現掃描完畢字樣
ProgressBar1.Position:=0;//初始狀態是0
Button1.Enabled:=true;
end;

對Word文件進行操作


使用CreateOleObject方法對WORD文檔操作具有先天所具備的優勢,與delphi所提供的那些控件方式的訪問相比,CreateOleObject方法距離WORD核心的操作「更近」,因為它直接使用OFFICE所提供的VBA語言對WORD文檔的操作進行編程。

作法很簡單,在視窗Form上放置了一個TEdit和一個TButton,每按一次按鈕,就會自動把Edit中的內容添加在背景作業word文檔中,當程序關閉時文件自動儲存至當前程序目錄中。

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Comobj, WordXP, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
//全域變數
FWord: Variant;
FDoc: Variant;


implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
FWord.Selection.TypeParagraph; //換行
FWord.Selection.TypeText(Text := form1.Edit1.Text);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
//首先創建對象,如果出現異常就作出提示
try
FWord := CreateOleObject('Word.Application'); //創建Word物件
FWord.Visible := False; //WORD程序的執行是否可見,值為False時程序在後台執行
except
ShowMessage('創建word對像失敗!');
Exit;
end;

//先在打開的Word中創建一個新的頁面,然後在其中鍵入"Hello,"+回車+"World!"
try
FDoc := FWord.Documents.Add;
FWord.Selection.TypeText(Text := 'Hello,');
FWord.Selection.TypeParagraph; //換行
FWord.Selection.TypeText(Text := 'World! ');
except
on e: Exception do
ShowMessage(e.Message);
end;
end;
//在程序關閉時把文件內容保存到當前目錄中,並以test.doc命名,同時關閉WORD程序
procedure TForm1.FormDestroy(Sender: TObject);
begin
FDoc.SaveAs(ExtractFilePath(application.ExeName) +'test.doc'); //存檔
FWord.Quit; //離開
FWord := Unassigned; //取消分派
end;
end.

星期一, 9月 17, 2007

如何連結access 2007的accdb資料庫

同樣的也是用ADOConnection來連結
提供者要選擇
Microsoft Office 12.0 Access Database Engine OLE DB Provider,若沒有可能要去下列連結安裝
http://www.microsoft.com/downloads/details.aspx?displaylang=zh-tw&FamilyID=7554f536-8c28-4598-9b72-ef94e038c891
接著在 連線->資料來源->手動輸入位置及檔名
最後在最下方 測試連線

星期五, 9月 14, 2007

串流壓縮方法

壓縮程度有4個,分別是clNone, clDefault, clFastest, clMax;

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ZLib, ExtCtrls; //ZLib記得要加進去喔

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Image1: TImage;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
//TmemoryStream壓縮
procedure CompressBitmap(var CompressedStream: TMemoryStream;const CompressionLevel: TCompressionLevel);
var
SourceStream: TCompressionStream;
DestStream: TMemoryStream;
Count: Integer;
Begin
Count := CompressedStream.Size;
DestStream := TMemoryStream.Create;
SourceStream:=TCompressionStream.Create(CompressionLevel, DestStream);
Try
CompressedStream.SaveToStream(SourceStream);
SourceStream.Free;
CompressedStream.Clear;
CompressedStream.WriteBuffer(Count, SizeOf(Count));
CompressedStream.CopyFrom(DestStream, 0);
finally
DestStream.Free;
end;
end;
//TmemoryStream解壓縮
procedure UnCompressBitmap(const CompressedStream: TFileStream; var Bmp: TBitmap);
var
SourceStream: TDecompressionStream;
DestStream: TMemoryStream;
Buffer: PChar;
Count: Integer;
Begin
CompressedStream.ReadBuffer(Count, SizeOf(Count));
GetMem(Buffer, Count);
DestStream := TMemoryStream.Create;
SourceStream := TDecompressionStream.Create(CompressedStream);
Try
SourceStream.ReadBuffer(Buffer^, Count);
DestStream.WriteBuffer(Buffer^, Count);
DestStream.Position := 0;
Bmp.LoadFromStream(DestStream);
finally
FreeMem(Buffer);
DestStream.Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
dc:hdc;
mycanvas:TCanVas;
Bmp:TBitmap;
MStream: TMemoryStream; //宣告記憶體的串流
begin
application.Minimize;
application.ProcessMessages;

mycanvas:=TCanvas.Create;
Bmp:=tbitmap.Create;
MStream := TMemoryStream.Create; //建立記憶體的串流
dc:=getdc(0);
try
myCanvas.Handle := DC;
Bmp.Width := Screen.Width;
Bmp.Height := Screen.Height;
Bmp.Canvas.CopyRect(Rect(0,0,Screen.Width,Screen.Height),myCanvas,Rect(0,0,Screen.Width,Screen.Height));

Bmp.SaveToStream(MStream); //將Bmp儲存到串流中
CompressBitmap(MStream, clMax); //壓縮Bitmap探用ClMax為最大壓縮,並儲存至MStream
MStream.SaveToFile('test.dat'); //將MStream儲存至檔案
finally
releasedc(0,dc);
mycanvas.Free;
Bmp.Free;
MStream.Free; //釋放記憶體的串流
end;
application.Restore;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
CompressedStream: TFileStream; //宣告記憶體的串流
Bmp: TBitmap;
begin
Bmp := TBitmap.Create;
CompressedStream := TFileStream.Create('test.dat' , fmOpenRead); //建立檔案串流,並讀取至CompressedStream
Try
UnCompressBitmap(CompressedStream, Bmp); //呼叫解壓縮Bitmap函式
image1.Picture.Bitmap.Assign(Bmp);
finally
Bmp.Free;
CompressedStream.Free; //釋放記憶體的串流
end;
end;

end.

用ListBox 選擇 Item (包括全選、反向選擇)


新增
5個按鈕TButton
1個TListBox, MultiSelect=true
1個TMemo

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
ListBox1: TListBox;
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.SelectAll; //全選
end;

procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
begin
for i:=0 to ListBox1.Count-1 do
begin
ListBox1.Selected[i]:=(not ListBox1.Selected[i]);
end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
ListBox1.ClearSelection;
end;

procedure TForm1.Button4Click(Sender: TObject);
var
i: integer;
begin
Memo1.Clear; // 先清除Memo1的內容
Memo1.Lines.Add('你這次選了以下的選項');
for i:=0 to ListBox1.Count-1 do
if (ListBox1.Selected[i]) then
Memo1.Lines.Add(ListBox1.Items.Strings[i]);

if (Memo1.Lines.Count=1) then // 沒有選擇任何一個
begin
Memo1.Clear;
Memo1.Lines.Add('你沒有選擇任何一個');
end;
end;

procedure TForm1.Button5Click(Sender: TObject);
var
i: integer;
begin
if (ListBox1.SelCount=0) then exit; // 沒有選擇任何一個
for i:=0 to ListBox1.Count-1 do // 找出點選了哪個
if ListBox1.Selected[i] then
Memo1.Lines.Add(ListBox1.Items.Strings[i]); // 加到右邊

ListBox1.DeleteSelected; // 刪除左邊
end;
end.

資料結構範例


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

type
TDateRec = record
Year: integer;
Month: (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec); //Month為1月到12月的英文字
Day: 1..31; //day為1~31的數值
end;

type
Name = record
FirstName: string;
LastName: string;
end;

type
Employee = record
EmName: Name; //Name為上面定義的結構包括FirstNmae及LastName
Addr: string;
Phone: string;
Salary: integer;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
test: Employee; //這兩個結構之後用到,可以得知Name的結構並不須要宣告
Dnow: TdateRec;
begin
test.EmName.FirstName:='123';
test.Addr :='456';
test.Phone:='333';
Dnow.year:=2006;
Dnow.Month:=Jun;
Dnow.Day :=30;
end;
end.

視窗Form的FormStyle屬性

1fsNormal一般模式
2fsMDIForm主視窗設成 fsMDIForm,所有子視窗設成 fsMDIChild,除了主視窗外,則所有子視窗都會動態建立,而不是靜態建立
3fsMDIChild
4fsStayOnTop顯示視窗在最上方

目錄交談視窗


新增5個TLabel
1個TEdit, Text=*.*
1個TFileListBox, FileEdit=Edit1, IntegralHeight=true(重新調整大小), 事件OnDbClick點兩下加入(以後用)
1個TFilterComboBox, FileList=FileListBox1, Filter=All files (*.*)*.*Executable files (*.exe)*.exeExecutable files (*.com)*.comDos batch files (*.bat)*.batDos Pif files (*.pif)*.pifWindows help files (*.hlp)*.hlpWindows bitmap files (*.bmp)*.bmpText files (*.txt)*.txt
1個TDirectoryListBox, DirLabel=Label4, FileList=FileListBox1(這兩個要在Events裡面才看得見)
1個TDriveComboBox1, DirList=DirectoryListBox1, 在事件OnChange點兩下加入(以後用)

程式碼

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, FileCtrl;

type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Edit1: TEdit;
FileListBox1: TFileListBox;
FilterComboBox1: TFilterComboBox;
DirectoryListBox1: TDirectoryListBox;
DriveComboBox1: TDriveComboBox;
Button1: TButton;
Button2: TButton;
procedure FileListBox1DblClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure DriveComboBox1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(Label4.Caption+'\'+Edit1.text);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
close;
end;

procedure TForm1.DriveComboBox1Change(Sender: TObject);
begin
DirectoryListBox1.Drive := DriveComboBox1.Drive;
FileListBox1.Drive := DriveComboBox1.Drive;
FileListBox1.Directory := DirectoryListBox1.Directory;
end;

procedure TForm1.FileListBox1DblClick(Sender: TObject);
begin
Button1.Click;
end;
end.

各式訊息視窗



unit Msgdlg;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
procedure Button5Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Hello World!!');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessagePos('Hello World!!', 10, 20);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
TheCaption, TheText: String;
begin
TheCaption := '訊息標題';
TheText := '訊息目的';
if Application.MessageBox(PChar(TheText), PChar(TheCaption), MB_DEFBUTTON1 + MB_ICONEXCLAMATION + MB_OKCANCEL) = IDOK then
ShowMessage('你選擇 OK')
else
ShowMessage('你選擇 Cancel');
end;

procedure TForm1.Button4Click(Sender: TObject);
var
W: Word;
S: String;
begin
W := MessageDlg('選擇是、否或忽略', mtInformation, [mbYes, mbNo, mbIgnore], 0);
case W of
mrYes: S := 'Yes';
mrNo: S := 'No';
mrIgnore: S := 'Ignore';
end;
ShowMessage('你選擇 ' + S);
end;

procedure TForm1.Button5Click(Sender: TObject);
var
W: Word;
S: String;
X, Y: Integer;
begin
X := 50; Y := 75;
W := MessageDlgPos('選擇終止、重試或忽略', mtWarning, mbAbortRetryIgnore, 0, X, Y);
case W of
mrAbort: S := 'Abort';
mrRetry: S := 'Retry';
mrIgnore: S := 'Ignore';
end;
ShowMessage('你選擇 ' + S);
end;
end.

星期四, 9月 13, 2007

檔案->最近瀏覽的5個檔案列出



首先加入TOpenDialog,然後在Filter設定為All fies (*.*)|*.*。
接著新增一個TMainMenu
然後在其底下新增一個Name=d1, Caption=檔案 (&F)
Name=N1, Caption=開啟 (&O), ShortCut=Ctrl+O, 事件Onclick連點(未來用)
Name=N2, Caption=結束 (&C), ShortCut=Ctrl+C, 事件Onclick連點(未來用)
Name=N3, Caption=-, Visible=false
Name=N1name1, Caption=&1 name, Visible=false, 事件Onclick = N1name1Click(以後會有這個事件)
Name=N2name1, Caption=&2 name, Visible=false, 事件Onclick = N1name1Click(以後會有這個事件)
Name=N3name1, Caption=&3 name, Visible=false, 事件Onclick = N1name1Click(以後會有這個事件)
Name=N4name1, Caption=&4 name, Visible=false, 事件Onclick = N1name1Click(以後會有這個事件)
Name=N5name1, Caption=&5 name, Visible=false, 事件Onclick = N1name1Click(以後會有這個事件)


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus;

type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
d1: TMenuItem;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N1name1: TMenuItem;
N2name1: TMenuItem;
N3name1: TMenuItem;
N4name1: TMenuItem;
OpenDialog1: TOpenDialog;
N5name1: TMenuItem;
procedure N1name1Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure N1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.N1Click(Sender: TObject);
var
s: string;
i, k: Integer;
begin
if OpenDialog1.Execute then
begin
if not N3.Visible then
N3.Visible := True; { Make separator visible }
k := d1.IndexOf(N1name1);
for i := d1.Count - 1 downto k + 1 do
begin { Move current filenames down one position }
s := d1.Items[i - 1].Caption;
s[2] := Chr(Ord('0') + (i - k + 1)); { Alt-Shortcut }
d1.Items[i].Caption := s;
d1.Items[i].Visible := d1.Items[i - 1].Visible;
end;
N1name1.Caption := '&1 ' + OpenDialog1.Filename;
N1name1.Visible := True;
ShowMessage('Adding: ' + OpenDialog1.Filename);
end;
end;

procedure TForm1.N1name1Click(Sender: TObject);
var
Filename: string;
begin
Filename := TMenuItem(sender).Caption;
System.Delete(Filename, 1, 2);
ShowMessage('Selected: ' + Filename);
end;

procedure TForm1.N2Click(Sender: TObject);
begin
close;
end;
end.

設計一個數位時鐘



新增加一個Timer、一個Label,在Timer的事件加入下列文字:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Label1.Caption := TimeToStr(Time);
end;

TGifImage 的重要屬性

重要的屬性(Property)介紹
1AnimationSpeedDetermines the relative speed of the GIF animation.
2AspectRatio

Pixel Aspect Ratio.

3BackgroundColorSpecifies the background color of an animated GIF.
4BackgroundColorIndexSpecifies the background color index of an animated GIF.
5Bitmap

Provides access to the bitmap representation of the GIF.

6BitsPerPixel

Determines the maximum color depth of the GIF.

7ColorReductionSpecifies the color reduction method used when importing images with more than 256 colors.
8ColorResolutionDetermines the maximum color depth of the GIF.
9Compression

gcLZW

gcRLE

10DitherMode

dmNearest

dmFloydSteinberg

dmStucki

dmSierra

dmJaJuNI

dmSteveArche

dmBurkes

dmOrdered

11DrawBackgroundColorSpecifies a custom background color of an animated GIF.
12DrawOptionsControls how the GIF is displayed.
13GlobalColorMapGives access to the GIFs Global Color Map.
14HeaderGives access to the GIF file header.
15ImagesLists the individual frames of the GIF image.
16IsTransparentDetermines if the GIF uses transparency.The IsTransparent property can be used to determine if the GIF uses transparency.
17PaintersMaintains a list of paint threads used by the GIF object.
18ReductionBits

Specifies the palette size when importing images with more than 256 colors using the Quantization method.

rmNone

rmWindows20

rmWindows256

rmWindowsGray

rmMonochrome

rmGrayScale

rmNetscape

rmQuantize

rmQuantizeWindows

rmPalette

19ThreadPrioritySpecifies the priority of the GIF's paint threads.
20VersionSpecifies the GIF version level.

TJpegImage 的重要屬性

重要的屬性(Property)介紹
1CompressionQuality當你要儲存jpeg時,這個屬性決定的壓縮品質,範圍是1到100,1表示壓縮最大品質最差,100表示壓縮最小,品質最高
2Grayscale

1.用來得知載入的影像是不是8bits的灰階影像

2.輸出將原本的彩色影像變成8bits灰階

3SaveToFile影像的高度(尺寸大小)
4Palette該屬性可以取得或設定新的色盤,當影像是不需要色盤時,該屬性為0
5Performance

決定載入影像的品質

jpBestQuality表示以最佳品質方式載入

jpBestSpeed 表示以最快的速度方式載入

6PixelFormat

像素的顏色深度

jf8Bit表示該影像為8位元的影像

jf24Bit 表示該影像為24位元的影像,一般的jpeg都是24位元的影像

7ProgressiveDisplay當jpeg顯示來源是從網路等緩慢的下載方式時,你可以考慮將它設為true。從硬碟等快速的裝置載入時如果將設為true時只是降低顯示的速度而已。
8ProgressiveEncoding在存檔壓縮時,將它設為true可以讓影像在載入的時候慢慢的先顯示出來,建議設為false
9Scale

決定載入圖片的尺寸大小,這個可以方便讓你顯示縮圖,當你設成jsHalf到jsEighth時你會發顯載入的速度加快了。

jsFullSize:顯示完整的尺寸

jsHalf: 顯示1/2的尺寸

jsQuarter:顯示1/4的尺寸

jsEighth:顯示1/8的尺寸

10Smoothing

這個屬性只有當ProgressiveDisplay為true時才有用

當設為true時,載入當中的影像區塊顯示,會先以以柔和模糊的區塊代替

11Width影像的高度(尺寸大小)


重要的方法(Method)介紹
1Assign可以拷貝一個Bitmap進來
2LoadFromFile從檔案中載入jpeg檔
3SaveToFile儲存jpeg至檔案中


重要的事件(Event)介紹
1OnProgress你可以利用這個事件監控影像載入的進度
2OnChange當影像內容有變化時,就會產生這個事件

讀取Gif檔案



首先可到此下載 http://finn.mobilixnet.dk/delphi/ Gif所需用到的GIFImage.pas檔案(依Delphi的版本去下載)

uses GIFImage;

procedure TForm1.Button1Click(Sender: TObject);
var
gif: TGifImage;
begin
gif := TGifImage.Create;
try
gif.Assign(Bmp);
gif.SaveToFile('test.gif');
finally
gif.Free;
end;
end;

星期三, 9月 12, 2007

跟系統註冊一個hotkey (隨時能偵測按鍵及滑鼠)


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
id:integer; //熱鍵id
procedure WMHotKey(var Msg : TWMHotKey); message WM_HOTKEY;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
Const
{ALT、CTRL和F12鍵的虛擬鍵值}
MOD_ALT = 1;
MOD_CONTROL = 2;
VK_R = 82;
begin
if GlobalFindAtom('MyHotkey') = 0 then
begin
{註冊全局熱鍵Ctrl + Alt + R}
id:=GlobalAddAtom('MyHotkey');
RegisterHotKey(handle,id,MOD_CONTROL+MOD_Alt,VK_R);
end else
halt;
end;

procedure TForm1.WMHotKey (var Msg : TWMHotKey);
begin
if msg.HotKey = id then
ShowMessage('Ctrl+Alt+R 鍵被按下!');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
UnRegisterHotKey(handle,id);
GlobalDeleteAtom(id);
end;
end.

Delphi 中的顏色

clBlack黑色Black
clMaroon栗色Maroon
clGreen綠色Green
clOlive橄欖綠Olive green
clNavy深藍色Navy blue
clPurple紫色Purple
clTeal深青色Teal
clGray灰色Gray
clSilver銀色Silver
clRed紅色Red
clLine淺綠色Lime green
clBlue藍色Blue
clFuchsia紫紅色Fuchsia
clAqua淺綠色Aqua
clWhite白色White
clBackground當前的系統桌面的背景顏色
clActiveCaption當前的被激活窗口的標題欄的顏色
clInactiveCaption當前的沒有被激活的窗口的標題欄的顏色
clMenu當前的菜單背景的顏色
clWindow當前的窗口背景的顏色
clWindowFrame當前的窗口框架的顏色
clMenuText當前的菜單上的文本的顏色
clCaptionText當前的被激活窗口的標題欄的文本的顏色
clActiveBorder當前的被激活窗口的邊界顏色
clInactiveBorder當前的沒有被激活窗口的邊界顏色
clAppWorkSpace當前的應用程序工作區的顏色
clHighlight當前的被選擇文本的背景顏色
clHighlightText當前的被選擇文本的顏色
clBtnFace當前的按鈕表面的顏色
clBtnShadow當前的按鈕投影的陰影顏色
clGrayText當前的無效文本的顏色
clBtnText當前的按鈕上文本的顏色
clInactiveCaptionText當前的被激活窗口標題欄的文本顏色
clBtnHighlight當前的按鈕上高亮度的顏色
cl3DDkShadow只有對Windows95或NT4.0系統:三維顯示元素陰影的顏色
cl3DLight只有對Windows95或NT4.0系統:對於三維顯示元素的亮面(朝向光源的面)
clInfoText只有對Windows95或NT4.0系統:ToolTip(工具提示)的文本顏色
clInfoBk只有對Windows95或NT4.0系統:ToolTip(工具提示)的背景顏色

修改文件檔案屬性

faReadOnly :唯讀
faHidden :隱藏
faSysFile :系統
faVolumeID :卷標
faDirectory :目錄
faArchive :存檔
faAnyfile :所有類型


//將文件檔案屬性設為隱藏
procedure TForm1.Button1Click(Sender: TObject);
var
f:integer;
begin
f := fileGetAttr('test.sys');//得到文件屬性;
if f and faHidden = 0 then //是否有隱藏屬性;
fileSetAttr('test.sys',faHidden);//設定為隱藏;
end;

{
//用以下寫法來判斷、顯示訊息也可以
case FileGetAttr('c:\command.dos') of
faResdOnly:ShowMessage('ReadOnly');
faHidden:ShowMessage('Hidden');
faSysFile:ShowMessage('SystemFile');
faVolumeID:ShowMessage('VolumeID');
faDirectory:ShowMessge('Directory');
faArchive:ShowMessage('Archive');
faAnyFile:ShowMessage('AnyFile');
else
ShowMessage('檔案不詳');

//用以下寫法來修改屬性也可以
if FileSetAttr('c:\autoexec.dos',faReadOnly)=0 then
ShowMessage('修改成功')
else
ShowMessage('修改失敗');
}

星期二, 9月 11, 2007

OpenDialog 開啟檔案

我通常會新增一個按鈕,上面文字為"..",然後再新新一個OpenDialog元件,其中要注意是Filter屬性,加入下列文字
組態設定檔(*.ini)¦*.ini¦所有檔案(*.*)¦*.* //Filter name¦Filter
然後在button的onclick加入下列文字

procedure TFlogin.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
Edit1.Text:= OpenDialog1.FileName;
end;
end;

使用Inc檔案

Delphi可以像C一樣用Inc文件
用編譯指令 {$I FileName}

如:
File1.inc 內容為
const
CText = 'Hello World!';


Unit1.pas
//.............
procedure TForm1.Button1Click(Sender: TObject);
{$I File1.inc} //答案就在這一行
Begin
ShowMessage(CText);
end;
//.............

Delphi 使程式碼簡潔的忠告

一、Boolean值操作應該是直接的
if If_Love_Delphi then
  Result:=True
else
  Result:=False;
改成這樣寫比較好:
Result:= If_Love_Delphi;

二、避免使用 if/then/if ,而用and来代替
例1:
if If_Love_Delphi then
  if If_Love_Linux then
    TryKylix(Now);
改成這樣寫比較好:
if If_Love_Delphi and If_Love_Linux then
  TryKylix(Now);
例2:
if If_Love_Delphi then
  if If_Love_Linux then
    Result:=True;
改成這樣寫比較好:
Result:= If_Love_Delphi and If_Love_Linux;

三、判斷boolean值時不需用"=True","=False"
if (If_Love_Delphi=True) and (If_Love_Linux=False) then
  DoNotTryLinux;
改成這樣寫比較好:
if If_Love_Delphi and not If_Love_Linux then
  DoNotTryLinux;


四、盡量不要用"+"來進行字串合併
ShowMessage('在下身高'+IntToStr(iHeight)+'尺,體重'+IntToStr(iWeight)+'公斤。');
改成這樣寫比較好:
ShowMessage(Format('在下身高%d,體重%d。', [iHeight,iWeight]));

五、盡量少用With,它不僅效率高,而且使程式碼更加容易讀
if Sender is TEdit then
  with Sender as TEdit do
    if (Text=') or (Text[SelStart]=') or (SelLength=Length(Text)) and (Key in ['a'..'z'] then
      Key:=UpCase(Key);
改成這樣寫比較好:
if Sender if TEdit then
  if (TEdit(Sender).Text=') or (TEdit(Sender).Text[TEdit(Sender).SelStart]=') or (TEdit(Sender).SelLength=Length(TEdit(Sender).Text)) and (Key in ['a'..'z']) then
    Key:=UpperCase(Key);

Delphi中預編譯指令的使用方法

一.指令介紹
1. DEFINE指令: 格式:{$DEFINE 名稱}
說明:用於定義一個在當前Unit有效的Symbol。定義了之後可以使用IF DEF 和 IFNDEF 
   指令來判斷該Symbol是否存在。

2. UNDEF指令: 格式:{$UNDEF 名稱}
說明:用於取消一個在當前Unit已經定義的Symbol。該指令和DEFINE配合使用。

3. IFDEF指令: 格式:{$IFNDEF 名稱}
說明:如果該指令後的名稱已經定義,則編譯該指令後直到{$ELSE}或{$ENDIF}之間的
程式碼。

4. IFNDEF指令: 格式:{$IFNDEF 名稱}
說明:如果該指令後的名稱已經定義,則編譯該指令後直到{$ELSE}或{$ENDIF}之間的
程式碼。

5. IFOPT指令: 格式:{$IFOPT 开关}
說明:如果該指令後的开关已經設立,則編譯該指令後直到{$ELSE}或{$ENDIF}之間的
   程式碼。

  6. ELSE指令: 格式:{$ELSE}
說明:透過前面的IFXXXX的條件來確定該指令到{$ENDIF}之間的程式碼是否應該被編
   譯或被忽略。

7. ENDIF指令: 格式:{$ENDIF}
說明:與IFXXXX配合,指明條件編譯程式碼的結束位置。

EX:

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
a : String;
end;

var
Form1: TForm1;

implementation
{$R *.DFM}

{$DEFINE AAA}

procedure TForm1.FormCreate(Sender: TObject);
begin
a := 'Other';
{$IFDEF AAA}
a := 'AAA';
{$ENDIF}
{$IFDEF BBB}
a := 'BBB';
{$ENDIF}
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Caption := a;
end;

end.

編譯後,按下Button,顯示“AAA”。
程式編譯了a := ’AAA。


如何快速的制作和更改版本:
  使用預編譯指令,在制作同一個程式的多個版本時,只需找出各版本中有區別的Unit,依次定義統一的版本Symbol,然後在程式中加入條件預編譯指令,就可以在實際編譯中取捨編譯不同的程式部份,這樣對於程式的規範性和保密性有很好的作用。
  然後,由于該類編譯指令只能作用於當前Unit,所以不能在一個公共Unit定義一次版本Symbol,而必須在各Unit中定義統一版本Symbol才行,因此,在更換版本時,需要確定所有的Symbol都已改變,這樣才能確保各版本的正確性,因此,可以使用Delphi IDE的Find in Files....(多個文件中尋找字串)的功能,找出所有定義版本Symbol的文件和位置,然後依次更改 保證所有位置已修改。

Delphi 鍵值大全 (包括滑鼠及鍵盤)

鍵盤使用常數16 (10)進位對應值對應按鍵
vk_Lbutton$01 (#1)Left Mouse Button
vk_Rbutton$02 (#2)Right Mouse Button
vk_Cancel$03 (#3)Control-Break procress used
vk_MButton$04 (#4)Middle Mouse Button
vk_Back$08 (#8)BackSpace Key
vk_Tab$09 (#9)Tab key
vk_Clear$0C (#12)Clear Key
vk_Return$0D (#13)Return Key
vk_Shift$10 (#16)Shift Key
vk_Control$11 (#17)Ctrl Key
vk_Menu$12 (#18)Alt Key
vk_Pause$13 (#19)Pause Key
vk_Capital$14 (#20)Caps Lock Key
vk_Escape$1B (#27)ESC Key
vk_Space$20 (#32)Space Key
vk_Prior$21 (#33)PageUp Key
vk_Next$22 (#34)PageDown Key

vk_End

$23 (#35)End Key
vk_Home$24 (#36)Home Key
vk_Left$25 (#37)Left Arrow Key
vk_Up$26 (#38)Up Arrow Key
vk_Right$27 (#39)Right Arrow Key
vk_Down$28 (#40)Down Arrow Key
vk_Select$29 (#41)Select Key
vk_Print$2A (#42)PrintScreen Key
vk_Execute$2B (#43)Execute Key
vk_SnapShot$2C (#44)PrintScreen Key for Windows 3.0 or later
vk_Copy$2C (#44)Not used by keyboards
vk_Insert$2D (#45)Insert Key
vk_Delete$2E (#46)Delete Key
vk_Help$2F (#47)Help Key
vk_0$30 (#48)0 Key
vk_1$31 (#49)1 Key
vk_2$32 (#50)2 Key
vk_3$33 (#51)3 Key
vk_4$34 (#52)4 Key
vk_5$35 (#53)5 Key
vk_6$36 (#54)6 Key
vk_7$37 (#55)7 Key
vk_8$38 (#56)8 Key
vk_9$39 (#57)9 Key
vk_A$41 (#65)A Key
vk_B$42 (#66)B Key
vk_C$43 (#67)C Key
vk_D$44 (#68)D Key
vk_E$45 (#69)E Key
vk_F$46 (#70)F Key
vk_G$47 (#71)G Key
vk_H$48 (#72)H Key
vk_I$49 (#73)I Key
vk_J$4A (#74)J Key
vk_K$4B (#75)K Key
vk_L$4C (#76)L Key
vk_M$4D (#77)M Key
vk_N$4E (#78)N Key
vk_O$4F (#79)O Key
vk_P$50 (#80)P Key
vk_Q$51 (#81)Q Key
vk_R$52 (#82)R Key
vk_S$53 (#83)S Key
vk_T$54 (#84)T Key
vk_U$55 (#85)U Key
vk_V$56 (#86)V Key
vk_W$57 (#87)W Key
vk_X$58 (#88)X Key
vk_Y$59 (#89)Y Key
vk_Z$5A (#90)Z Key
vk_NumPad0$60 (#96)Numeric KeyPad 0 Key
vk_NumPad1$61 (#97)Numeric KeyPad 1 Key
vk_NumPad2$62 (#98)Numeric KeyPad 2 Key
vk_NumPad3$63 (#99)Numeric KeyPad 3 Key
vk_NumPad4$64 (#100)Numeric KeyPad 4 Key
vk_NumPad5$65 (#101)Numeric KeyPad 5 Key
vk_NumPad6$66 (#102)Numeric KeyPad 6 Key
vk_NumPad7$67 (#103)Numeric KeyPad 7 Key
vk_NumPad8$68 (#104)Numeric KeyPad 8 Key
vk_NumPad9$69 (#105)Numeric KeyPad 9 Key
vk_Multiply$6A (#106)Mutiply Key
vk_Add$6B (#107)Add Key
vk_Separator$6C (#108)Sepatator Key
vk_Subtract$6D (#109)Subtract Key
vk_Decimal$6E (#110)Decimal Key
vk_Divide$6F (#111)Divide Key
vk_F1$70 (#112)F1 Key
vk_F2$71 (#113)F2 Key
vk_F3$72 (#114)F3 Key
vk_F4$73 (#115)F4 Key
vk_F5$74 (#116)F5 Key
vk_F6$75 (#117)F6 Key
vk_F7$76 (#118)F7 Key
vk_F8$77 (#119)F8 Key
vk_F9$78 (#120)F9 Key
vk_F10$79 (#121)F10 Key
vk_F11$7A (#122)F11 Key
vk_F12$7B (#123)F12 Key
vk_F13$7C (#124)F13 Reserve Key
vk_F14$7D (#125)F14 Reserve Key
vk_F15$7E (#126)F15 Reserve Key
vk_F16$7F (#127)F16 Reserve Key
vk_F17$80 (#128)F17 Reserve Key
vk_F18$81 (#129)F18 Reserve Key
vk_F19$82 (#130)F19 Reserve Key
vk_F20$83 (#131)F20 Reserve Key
vk_F21$84 (#132)F21 Reserve Key
vk_F22$85 (#133)F22 Reserve Key
vk_F23$86 (#134)F23 Reserve Key
vk_F24$87 (#135)F24 Reserve Key
vk_NumLock$90 (#144)NumLock Key
vk_Scroll$91 (#145)Scroll Lock Key

星期五, 9月 07, 2007

視窗Form淡入淡出的效果

先在form1新增一按鈕,並在按鈕的onClick加入下列程式:

form2.showmodal;

接著新增一個新的視窗為form2,並加入一個timer,其enabled=true 及 interval=100,並記得加入事件喔。最後新增一'離開的'按鈕,然後編輯程式碼如下:

unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;

type
TForm2 = class(TForm)
Button1: TButton;
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Timer1Timer(Sender: TObject);
var
i,j:integer;
begin
timer1.Enabled:=false;
i:=0;
j:=3;
while(i<255) do
begin
i:=i+j;
form2.AlphaBlendValue:=i;
end;
form2.AlphaBlendValue:=255;
end;

procedure TForm2.FormShow(Sender: TObject);
begin
form2.AlphaBlend:=true;
form2.AlphaBlendValue:=0;
timer1.Enabled:=true;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
var
i,j:integer;
begin
i:=255;
j:=3;
while(i>0) do
begin
i:=i-j;
form2.AlphaBlendValue:=i;
end;
form2.AlphaBlendValue:=0;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
close;
end;

end.

擷取畫面並存成BMP及JPG檔案


uses Windows, Graphics, Jpeg;

procedure TForm1.Button1Click(Sender: TObject);
var
dc:hdc;
MyCanvas:TCanVas;
Bmp:TBitmap;
Jpg: TJpegImage;
begin
application.Minimize; //視窗最小化
application.ProcessMessages; //視窗取得控制
//可能要delay一下,不然抓到空白東東
Jpg := TJpegImage.Create;
MyCanvas:=TCanvas.Create;
Bmp:=tbitmap.Create;
dc:=getdc(0);
try
MyCanvas.Handle := DC;

Bmp.Width := Width;
Bmp.Height := Height;
Bmp.Canvas.CopyRect(Rect(0,0,Screen.Width,Screen.Height),MyCanvas,Rect (0,0,Screen.Width,Screen.Height));
Image1.Picture.Bitmap.Assign(Bmp);
Bmp.SaveToFile('test.Bmp');

Jpg.Assign(Bmp);
Jpg.Performance:=jpBestQuality;
Jpg.CompressionQuality := 30; //你想要的壓縮品質
Jpg.Compress;
Jpg.SaveToFile('test.jpg');
finally
releasedc(0,dc);
MyCanvas.Free;
Bmp.Free;
end;
application.Restore; //視窗回復
end;

讀registry去取得"我的文件"目錄




uses registry;

procedure TForm1.Button1Click(Sender: TObject);
var
reg:Tregistry;
begin
//取得我的文件目錄
reg:=Tregistry.create;
reg.RootKey:=HKEY_USERS;
reg.OpenKey('\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders',false);
is_Personal:=reg.readstring('Personal'); //is_Personal是'我的文件'目錄位置
reg.CloseKey ;
reg.free;
end;

星期四, 9月 06, 2007

SMTP寄信程式



首先 我們先在Form上放下列元件:
7個Edit、7個Label、1個Button、1個Memo、1個IdSMTP(在Indy Client裡)、1個IdMessage(在Indy Misc裡)
接著就編輯Button1的onClick程式碼(以下內容):


procedure TForm1.Button1Click(Sender: TObject);
begin
try
IdSMTP1.AuthenticationType:=atLogin; //登陸類型
IdSMTP1.Username:=Edit1.Text; //使用者帳號
IdSMTP1.Password:=Edit2.Text; //使用者密碼
IdSMTP1.Host:=Edit3.Text; //SMTP伺服器位址
IdSMTP1.Port:=strtoint(Edit4.Text); //SMTP埠必須轉換為整數
IdSMTP1.Connect;
except
Showmessage('連線失敗!!');
Exit;
end;
IdMessage1.Body.Clear;//清除上次信件內容
IdMessage1.Body.Assign(Memo1.Lines);//信件內容
IdMessage1.From.Address:=Edit5.Text;//發信人地址
IdMessage1.Recipients.EMailAddresses:=Edit6.Text;//收信人地址
IdMessage1.Subject:=Edit7.Text;//信件主旨
try
IdSMTP1.Send(IdMessage1);
showmessage('發送成功!!');
except
showmessage('發送失敗!!有問題了!!');
end;
end;


若要加入密碼

uses
IdSASLLogin, IdUserPassProvider;

var
IdSASLLogin1 :TIdSASLLogin;
LHlogin :TIdUserPassProvider;
begin
IdSASLLogin1 :=TIdSASLLogin.Create();
LHlogin :=TIdUserPassProvider.Create();
IdSMTP1.Username:=sUsername;
IdSMTP1.Password:=sPassword;
LHlogin.Username:=sUsername;
LHlogin.Password:=sPassword;
IDSMTP1.AuthType:=atSASL;
IdSMTP1.SASLMechanisms.Add.SASL:=IdSASLLogin1;
IdSASLLogin1.UserPassProvider:=LHlogin;


try
IdSMTP1.Connect;

//IDSMTP1.ConnectTimeout := 1000;
//IdSMTP1.Connect(1000);
if IdSMTP1.Connected then
begin

if (Length(sUsername)) > 0 then
begin
if not IdSMTP1.Authenticate then
begin
//DebugStr('@@驗證失敗');//'郵件伺服器驗證失敗!'
exit;
end;
end;
IdSMTP1.Send(IdMessage1); //寄出報表
end;

finally
if IdSMTP1.Connected then IdSMTP1.Disconnect;
end;

如何寫一隻執行序(thread)的程式

首先開啟File->New->Other->Thread Object。
這時候會產生Unit1(寫視窗程式用)及Unit2(寫執行序用)
Unit2的內容為下:

unit Unit2;

interface

uses
Classes;

type
mythread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;

implementation

{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,

Synchronize(UpdateCaption);

and UpdateCaption could look like,

procedure mythread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }

{ mythread }

procedure mythread.Execute;
begin
{ Place thread code here } //這裡就是加入執行序程式碼的地方了
end;

end.


其中,你注意找到procedure mythread.Execute;,應找到了吧,連我都看到了,這就是你剛才建立的執行序了,那麼接下來,我們要做的就是加入後台執行的程式碼。
如果你要調用unit1上的元件,你可以在unit2上面的uses中加入unit1就行了。記住,在unit1裡的implementation後面增加uses unit2,這樣你就可在unit1中使用執行序了。
而引用的方法很簡單,就是mythread.Create(false);。OK,這就是delphi中的執行序,呵呵。

計算程式跑了多少時間


use windows;

private
p_Start, p_Cost : DWORD;

p_Start:=GetTickCount();//計算時間
程式....
p_Cost:=GetTickCount()-p_Start;
showmessage('spend time: '+format('%0.3n',[p_Cost/1000])+'s');

星期一, 9月 03, 2007

如何Debug

可能發生的問題:
無法看變數時:
Variable ??? inaccessible here due to optimization
Project Option Compiler 去掉Optimization

Alt+Ctrl+L 顯示Local Variables
Alt+Ctrl+W 顯示Watch List
Alt+Ctrl+S 顯示Call Stack 目前的執行事件

F5 加入中斷點

Ctrl+F5 加入觀察的變數
Ctrl+F7 看變數目前的值
Ctrl+F4 顯示求值框(未試驗)
Alt+F5 顯示檢查窗(未試驗)

F7 (Trace Into) 以逐行DEBUG,如果遇到另一個副程式(或函數)也跳到該程式內逐行DEBUG
F8 (Step Over) 也可以逐行DEBUG,但如果遇到另一個副程式(或函數)則直接傳回執行後的值
F4 (Run to Cursor) 直接執行到游標停留的行數
Shift+F7 (Trace to next source line) 執行到下一個單元unit(未試驗)
Shift+F8 (Run Until Return) 跑迴圈快一點,Debug跳出CPU視窗,執行到此函數或過程結束處(未試驗)

F9 (Compile and Run,編譯並執行)
Ctrl+Break (Program Pause,程序暫停) 再次按F9才會繼續再開始
Alt+F2 (Program Reset,程序中止)

在Breakpoint list設定中斷點的屬性Properties,這些都是設完屬性後,再按F9
1. Source Breakpoint 源碼中斷點
2. Condition 條件,設定條間中斷
3. Pass Count 通過次數,指令執行第幾次後中斷
4. Group 組,設定不同群組名,將可以用禁止或允許組(Disable Group/Enable Group)

高級除錯
執行序狀態(Thread Status):顯示當前程序中有多少執行序在運行,各執行序的狀態是什麼?參數是什麼?
模組(Modules):顯示當前程序使用了多少模組,其名稱和地址是多少?這對於調試DLL時很有用。
CPU/FPU:在彙編語言層次顯示代碼,這能夠更加精確地觀察程序是如何運行的,各暫存器是怎麼變化的。
過程附帶(Attach Process):為了除錯某些特殊程序(例如Windows 2000下的服務【Service】),允許先運行用戶程序,再運行除錯程序。
遠端除錯(Remote Debug):允許在一台電腦上執行用戶程序,在另外一台電腦上運行Delphi,通過網路進行除錯,這對於除錯大型程序很有用,也能除錯那些對系統有特殊要求的程序。

星期日, 9月 02, 2007

右下角工具列顯示,並有按右鍵的功能





unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ShellAPI, Menus;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
PopupMenu1: TPopupMenu;
asdf1: TMenuItem;
N2342341: TMenuItem;
N1: TMenuItem;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
procedure WndProc(var Msg: TMessage); override; // tray icon 的 call back function
{ Public declarations }
end;
const
WM_MYTRAYNOTIFY=WM_USER+1; //定義 wm message

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
tray_nid: TNotifyIconData;
tray_icon: TIcon;
begin
tray_icon:= TIcon.Create;
tray_icon.LoadFromFile('COLOR_BL.ICO');
tray_nid.cbSize := sizeof(tray_nid);
tray_nid.Wnd := self.Handle;
// blueicon 設定uID為 200
tray_nid.uID := 200;
tray_nid.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
// NIF_MESSAGE 設定 message wm_xxx
// NIF_ICON 設定 ICON
// NIF_TIP 設定 提示訊息
tray_nid.hIcon := tray_icon.Handle;
tray_nid.uCallbackMessage := WM_MYTRAYNOTIFY;
StrPCopy(tray_nid.szTip, '工具任按鈕提示');
Shell_NotifyIcon(NIM_ADD, @tray_nid);
tray_icon.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
tray_nid: TNotifyIconData;
begin
tray_nid.cbSize := sizeof(tray_nid);
tray_nid.Wnd := self.Handle;
// blueicon 設定為 200
tray_nid.uID := 200;
Shell_NotifyIcon(NIM_DELETE, @tray_nid);
end;

procedure TForm1.WndProc(var Msg: TMessage);
var
pt: TPOINT;
curpos, curaction, curicon: string;

begin
if Msg.Msg = WM_MYTRAYNOTIFY then
begin
// ICON 的 uID
case Msg.WParam of
200: curicon := 'blue icon mouse action: ';
300: curicon := 'green icon mouse action: ';
end;
GetCursorPos(pt);
curpos := 'X: '+IntToStr(pt.X)+', Y: '+IntToStr(pt.Y);
// 滑鼠的按鍵動作
case Msg.LParam of
WM_LBUTTONDOWN: curaction := 'Left Button Down ';
WM_RBUTTONDOWN: curaction := 'Right Button Down ';
WM_LBUTTONUP: curaction := 'Left Button Up ';
WM_RBUTTONUP:
begin
curaction := 'Right Button up ';
SetForegroundWindow(Handle); //隨意地方按左鍵就能消除
popupmenu1.popup(pt.X,pt.Y );
PostMessage(Handle,WM_NULL,0,0);
end;

WM_MOUSEMOVE: curaction := 'Mouse Move ';
WM_LBUTTONDBLCLK: curaction := 'Left Button DoubleClick ';
WM_RBUTTONDBLCLK: curaction := 'Right Button DoubleClick ';
end;
Memo1.Lines.Add(curicon+' '+curaction+' '+curpos); //訊息由目前的圖示,滑鼠位置及滑鼠按鍵 組成
end;
inherited;

end;

end.