星期四, 9月 20, 2012

Timer使用技巧

1. 可以使用TELTimerPool來一次新增多個Timer,並方便管理

2. 預設為Timer.Enabled := False; 於onFormShow再將Timer.Enabled := True;

3. 為避免onTimer內程式跑沒完,下個時間的觸發又到,可加旗標來防止下個時間的進入。

4. 可以設定第一次跑15秒後跑,之後是1分半後跑一次,則預設Timer.Interval:=15000。然後在onTimer的程式內寫Timer.Interval:=90000

5. Timer的第一次觸發是inteval時間完後才跑。

星期三, 9月 19, 2012

TStringList的AddObject使用方式

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
type
  PMyRec = ^TMyrec;
  TMyRec = record
    s: string;
    i: Integer;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  List: TStringList;
  R1,R2: TMyRec;
  str: string;
  i: Integer;
begin
  List := TStringList.Create;

  R1.s := 'abc';
  R1.i := 123;
  str := '我是字符串';
  List.AddObject('1', @R1);           {用 1 表示结构 TMyRec}
  List.AddObject('2', Sender);        {用 2 表示 TButton}
  List.AddObject('3', Self);          {用 3 表示 TForm1}
  List.AddObject('4', Pointer(str));  {用 4 表示 String}

  for i := 0 to List.Count - 1 do
  begin
    case StrToIntDef(List[i], 0) of
      1: begin
           R2 := PMyRec(List.Objects[i])^;
           ShowMessageFmt('%s,%d', [R2.s, R2.i]);       {abc,123}
         end;
      2: ShowMessage(TButton(List.Objects[i]).Caption); {Button1}
      3: ShowMessage(TForm1(List.Objects[i]).Text);     {Form1}
      4: ShowMessage(PChar(List.Objects[i]));           {我是字符串}
    end;
  end;

  List.Free;
end;

end.

字串還是要用record的方式
type
  TStringRec = record
    s: string;
  end;
  PStringRec = ^TStringrec;

implementation

{$R *.dfm}
procedure AddAllFetchParamList(AllFetchParamList1: TStringList; sFinalDate1, sNo1:string);
var
  FindIndex : integer;
  sRec      : PStringRec;
  tmpStr    : string;
begin
  FindIndex := AllFetchParamList1.IndexOf(sFinalDate1);
  if FindIndex>=0 then //表示有找到
  begin
    tmpStr := PStringRec(AllFetchParamList1.Objects[FindIndex])^.s+','+sNo1;
    PStringRec(AllFetchParamList1.Objects[FindIndex])^.s := tmpStr;
  end else begin
    new(sRec);
    sRec.s := sNo1;
    AllFetchParamList1.AddObject(sFinalDate1, TObject(sRec));
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  sl: TStringList;
  i: integer;
begin
  sl:= TStringList.Create;
  try
    AddAllFetchParamList(sl, '2011/01/01', '1');
    AddAllFetchParamList(sl, '2011/01/01', '2');
    AddAllFetchParamList(sl, '2011/03/01', '3');
    AddAllFetchParamList(sl, '2011/01/01', '4');
    AddAllFetchParamList(sl, '2011/03/01', '5');
  finally
    for i := 0 to sl.Count-1 do
      Dispose(PStringRec(sl.Objects[i]));
    sl.Free;
  end;
end;

TStringList可以以特定字元做分割及排除空白即分割的情況

var
  ASource: PChar;
  AStr: String;
  astr1: string;
  ACount,i: Integer;
  AStrings: TStringList;
begin
  ASource := 'WorkerW||tooltips_class32||NotifyWnd||MSCTFIME UI||IME||ComboLBox||Auto-Suggest Dropdown||ATL:00409BA8||#43||';
  AStrings := TStringList.Create;
  Memo1.Clear;
  try



  ACount := ExtractStrings(['|'], [' ','#','.'], ASource, AStrings);
    For i:=0 to ACount-1 do
    begin
            Memo1.Lines.Add(AStrings[i]);
  end;

星期二, 9月 18, 2012

判斷磁碟空間是否小於40M

procedure TForm1.Button1Click(Sender: TObject);
var
  btWorkDrive: Byte;
  DiskFreeSize: Int64;
begin
    //硬碟空間不夠,小於5m則跳出不存囉
    btWorkDrive := Ord(UpperCase('C:\test\')[1])-64; //g_sTempPath
    DiskFreeSize := DiskFree(btWorkDrive);
    if (DiskFreeSize<>-1) and ((DiskFreeSize div (1024*1024)){MB}<40) then
      Exit;
end;

星期五, 9月 07, 2012

取得AllUserAppData及LocalAppData的目錄

uses SHFolder;

const
  _BUFSZ = 516;
var
  buf: array[0.. _BUFSZ-1] of Char;
begin

  FillChar(buf[0],  _BUFSZ, 0);
  SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, @buf[0]);
  g_sLocalAppData := buf;
  FillChar(buf[0],  _BUFSZ, 0);
  SHGetFolderPath(0, CSIDL_COMMON_APPDATA, 0, 0, @buf[0]);
  g_sAllUserAppData := buf;

  sUserCfg := g_sLocalAppData+'\Microsoft\';
end;

星期二, 9月 04, 2012

取得檔案的修改時間

function GetFileAltertTime(FileName: string): string;
begin
  Result := FormatDateTime('yyyy-mm-dd hh:nn:ss', FileDateToDateTime(FileAge(FileName)));
end;

procedure TForm8.Button1Click(Sender: TObject);
begin
  caption := GetFileAltertTime('C:\Source\1.exe');
end;

判斷作業系統是否為Windows XP SP2+

//判斷作業系統是否為Windows XP SP2+
function IsXPSP2Above():boolean ;
var
  vi:   _OSVERSIONINFO;
begin
  Result:=False;
  FillChar(vi, SizeOf(vi), 0);
  vi.dwOSVersionInfoSize := SizeOf(vi);
  Windows.GetVersionEx(vi);

  // 作業系統
  if      (vi.dwMajorVersion=5) and (vi.dwMinorVersion = 1) and (Pos('Service Pack 2', AnsiString(vi.szCSDVersion)) > 0) then Result:=True  //Windows XP SP2
  else if (vi.dwMajorVersion=5) and (vi.dwMinorVersion = 1) and (Pos('Service Pack 3', AnsiString(vi.szCSDVersion)) > 0) then Result:=True  //Windows XP SP3
  else if (vi.dwMajorVersion=5) and (vi.dwMinorVersion = 2) then Result:=True  //Microsoft Windows Server 2003, Windows XP 64
  //(vi.dwMajorVersion=5) and (vi.dwMinorVersion = 0) Microsoft Windows 2000
  else if (vi.dwMajorVersion>5) then Result:=True;    //Vista+
end;

判斷是否有安裝Access趨動

uses Registry;

function IsInstallAccessDatabaseEngine: boolean;
var
  reg:          TRegistry;
begin
  Result := False;
  reg:=TRegistry.Create;
  try
    reg.RootKey:=HKEY_LOCAL_MACHINE;
    if (Reg.OpenKeyReadOnly('SOFTWARE\Classes\Microsoft.ACE.OLEDB.12.0')) or
      (Reg.OpenKeyReadOnly('SOFTWARE\Wow6432Node\Classes\Microsoft.ACE.OLEDB.12.0')) then
      Result := True;
  finally
    reg.CloseKey;
    reg.Free;
  end;
end;

星期一, 9月 03, 2012

取得固定硬碟的序號

procedure TForm1.Button1Click(Sender: TObject);
var
  VolumeSerialNumber : DWORD;
  MaximumComponentLength : DWORD;
  FileSystemFlags : DWORD;
  TheSerialNumber : String;
  DR: Char;
  RootPath: PChar;
begin
  for DR := 'C' To 'Z' Do
  begin
    RootPath := PChar(DR + ':\');
    if (GetDriveType(RootPath) = DRIVE_FIXED) Then
    begin
      if GetVolumeInformation(RootPath,nil,0,@VolumeSerialNumber,
         MaximumComponentLength,FileSystemFlags,nil,0) then
      begin
        TheSerialNumber := IntToHex(HiWord(VolumeSerialNumber), 4) +
                            IntToHex(LoWord(VolumeSerialNumber), 4);
      end;
      memo1.Clear;
      memo1.Lines.Add( Format('固定磁碟序號:%s',[TheSerialNumber]) );
    end;
  end;
end;

星期四, 1月 05, 2012

hint提示設定

Application.HintPause:=500;{延遲時間}
Application.HintColor:=$00CEF3E7;{提示的顏色}
Application.HintHidePause:=10000;{提示時間}
Application.HintShortPause:=100;{兩個提示中間的間隔}

檢測Shift、Alt和Ctrl鍵 & 滑鼠左鍵、中鍵、雙擊、右鍵

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Shift >= [ssShift] then
    label1.Caption := '你按下了Shift鍵';
  if Shift >= [ssAlt] then
    label1.Caption := '你按下了Alt鍵';
  if Shift >= [ssCtrl] then
    label1.Caption := '你按下了Ctrl鍵';
end;
 
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Shift >= [ssLeft] then
    label1.Caption := '你單擊鼠標左鍵';
  if Shift >= [ssMiddle] then
    label1.Caption := '你單擊鼠標中鍵';
  if Shift >= [ssDouble] then
    label1.Caption := '你雙擊了鼠標';
  if ssRight in Shift then
    label1.Caption := '你單擊鼠標右鍵';
end;

星期五, 12月 02, 2011

取得檔案的建立時間、修改時間及訪問時間

procdeure GetFileTime(const Tf:string);
{ 獲取文件時間,Tf表示目標文件路徑和名稱 }
const
Model='yyyy/mm/dd,hh:mm:ss'; { 設定時間格式 }
var
Tp:TSearchRec; { 申明Tp為一個查找記錄 }
T1,T2,T3:string;

begin
FindFirst(Tf,faAnyFile,Tp); { 查找目標文件} T1:=FormatDateTime(Model,
CovFileDate(Tp.FindData.ftCreationTime)));
{ 返回文件的創建時間 }
T2:=FormatDateTime(Model,
CovFileDate(Tp.FindData.ftLastWriteTime)));
{ 返回文件的修改時間 }
T3:=FormatDateTime(Model,Now));
{ 返回文件的當前訪問時間 }
FindClose(Tp);
end;

星期四, 11月 24, 2011

設定元件位置在點擊按鈕的正上方

unit Unit1;

interface

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

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

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  point1: TPoint;
begin
  point1:=Button1.Parent.ClientToScreen(Button1.BoundsRect.TopLeft);
  point1:=ClientToScreen(point1);
  caption := 'X:'+IntToStr(point1.x)+' '+
    'Y:'+IntToStr(point1.y);
  Form2:= TForm2.Create(self);
  try
    Form2.SetPosition(point1.x, point1.y); //x右邊到元件 y上邊到元件
    Form2.ShowModal;
  finally
    Form2.Free;
  end;
end;

end.
unit Unit2;

interface

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

type
  TForm2 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
    procedure SetPosition(x, y: Integer);
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.SetPosition(x, y: Integer);
begin
  self.left:=x-(self.Width div 2);
  self.Top:=y-self.Height;
end;

end.

星期三, 11月 23, 2011

ms sql 檢查資料表及資料表中的資料欄是否存在


在"資料表"的"欄位"存在,傳回1;"欄位"不存在,傳回0
select count(name) from syscolumns
where id=(
select id from sysobjects
where name='資料表名稱')
and name='欄位名稱'

判斷資料表存不存在
select * from doctor..sysobjects where name='病人' and type='U')
doctor is 資料庫名稱
病人是資料表的名稱

星期四, 11月 17, 2011

combobox自動展開及關閉

新增cxcombobox,並加上item值,再加入下列事件:
procedure TForm1.cxComboBox1MouseEnter(Sender: TObject);
begin
  cxComboBox1.DroppedDown:=true;
end;

procedure TForm1.FormMouseEnter(Sender: TObject);
begin
  cxComboBox1.DroppedDown:=false;
end;

星期一, 11月 14, 2011

StrToDate要注意短日期時間格式

var
t:TDateTime;
fs:TFormatSettings;
begin
fs.ShortDateFormat:='yyyy-mm-dd';
fs.DateSeparator:='-'; //這一行一定要有
t := StrToDate('2010-01-01',fs);

取得當日開始及最後時間

//******************************************************************************
//* GetDayStartDT: 取得當日開始時間AM 00:00:01:00                              *
//******************************************************************************
function mDayStartDT(tmpDT: TDateTime): TDateTime;
var
  wYear, wMonth, wDay: WORD;
begin
  DecodeDate(tmpDT, wYear, wMonth, wDay);
  Result := EncodeDate(wYear, wMonth, wDay)+
            EncodeTime(0, 0, 0, 0);
end;
//******************************************************************************
//* GetDayEndDT: 取得當日結束時間PM 23:59:59:00                                *
//******************************************************************************
function mDayEndDT(tmpDT: TDateTime): TDateTime;
var
  wYear, wMonth, wDay: WORD;
begin
  DecodeDate(tmpDT, wYear, wMonth, wDay);
  Result := EncodeDate(wYear, wMonth, wDay)+
            EncodeTime(23, 59, 59, 0);
end;

星期三, 10月 05, 2011

設定短日期時間格式及日曆格式

  var
    m_pcDateFormat: array[0..127] of Char;  // for locale setting
    m_pcCalendarFormat: array[0..127] of Char;
  begin
    FillChar(m_pcDateFormat, 127*SizeOf(Char), 0);
    FillChar(m_pcCalendarFormat, 127*SizeOf(Char), 0);
    //取得日期格式資訊,並存放置 m_pcDateFormat 中
    GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, m_pcDateFormat, 127) ;

    //取得日曆格式,並存放置 m_pcCalendarFormat 中
    GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_ICALENDARTYPE, m_pcCalendarFormat, 127) ;

    //設定日期格式為 yyyy/MM/dd
    SetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, 'yyyy/MM/dd');

    //設定日曆格式為1型式  (1="西曆 (中文)" 4="中華民國曆")
    SetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_ICALENDARTYPE, '1');

    //還原
    SetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, m_pcDateFormat);
    SetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_ICALENDARTYPE, m_pcCalendarFormat);
  end;

星期一, 9月 05, 2011

將數字轉成容量大小或貨幣的字串(3位數一個逗點)

FormatFloat('###,###,###,##0',iFileSize);