星期一, 3月 31, 2008

判斷磁碟機是否有效

可判斷磁碟機,如A槽或光碟槽是否有效

function ValidDrive( driveletter: Char ): Boolean;
var
mask: String[6];
sRec: TSearchRec;
oldMode: Cardinal;
retcode: Integer;
begin
oldMode :=SetErrorMode( SEM_FAILCRITICALERRORS );
mask:= '?:\*.*';
mask[1] := driveletter;
{$I-} { don't raise exceptions if we fail }
retcode := FindFirst( mask, faAnyfile, SRec );
if retcode = 0 then
FindClose( SRec );
{$I+}
Result := Abs(retcode) in
[ERROR_SUCCESS,ERROR_FILE_NOT_FOUND,ERROR_NO_MORE_FILES];
SetErrorMode( oldMode );
end; { ValidDrive }

星期二, 3月 25, 2008

防呆裝置,無效的按鍵不能按


procedure TFormMain.SpinTotalTimeKeyPress(Sender: TObject;var Key: Char);
begin
if (Key='-') or (Key='.') or (Key='+') then Key:=char(0);
end;

function CheckLegalSpinValue( var spin:TSpinEdit; var Key:Word ):boolean;overload;
begin
//if not( Key in [$9, $30..$57, $60..$69, $D, $A, $25, $27, $90, VK_BACK, VK_DELETE] ) then
//應觀眾要求修改 20070625 Ma
if not( Key in [$9, $30..$57, $60..$69, $D, $A, $25, $26, $27, $28, $90, VK_BACK, VK_DELETE] ) then
begin
OneBtnMsgBox(g_saMsg[27], MB_ICONSTOP) ; // '請輸入合法的數字'
spin.Value := 0 ;
Result := false ; // defined in windows
Exit ;
end ;
Result := true ;
end ;


{ check if the input in TSpinEdit is legal }
function CheckLegalSpinValue( var spin:TSpinEdit):boolean;overload;
begin
if( IsLegalInt(spin.Text) ) then
Result := true
else
Result := false ;
end ;

procedure TFrame3.SpinEdit1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if( not CheckLegalSpinValue(SpinEdit1, Key) ) then
Exit;
end;

星期四, 3月 20, 2008

月利率來看,則存入多少金額可獲得最高報酬利率


procedure TForm1.Button1Click(Sender: TObject);
var
i : double;
j : integer;
want_money : integer;
begin
if Edit2.text='0' then
j := 1
else
j := strtoint(Edit2.text);
i := trunc(j*strtofloat(Edit1.Text)/1200+0.4)+0.5;
want_money := trunc(i*1200/strtofloat(Edit1.Text)+0.5);
Label3.Caption := floattostr(want_money);
Label4.Caption := floattostr((i+0.5)*1200/want_money);
Label5.Caption := floattostr(i+0.5);
end;

星期三, 3月 19, 2008

記錄平均cpu使用率多少的程式

主程式,新增一個TMemo,一個Timer

unit fmTest;

interface

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

type
TTestForm = class(TForm)
MInfo: TMemo;
LbAldynUrl: TLabel;
Timer: TTimer;
procedure LbAldynUrlClick(Sender: TObject);
procedure TimerTimer(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
TestForm: TTestForm;

implementation

{$R *.DFM}

uses shellapi;

procedure TTestForm.LbAldynUrlClick(Sender: TObject);
begin
ShellExecute(Application.Handle, 'open', 'http://www.aldyn.ru/',
nil, nil, SW_SHOWDEFAULT);
end;

procedure TTestForm.TimerTimer(Sender: TObject);
var i: Integer;
begin
CollectCPUData;
MInfo.Lines.BeginUpdate;
for i:=0 to GetCPUCount-1 do
MInfo.Lines[i+1]:=Format('CPU #%d - %5.2f%%',[i,GetCPUUsage(i)*100]);
MInfo.Lines.EndUpdate;
end;

procedure TTestForm.FormCreate(Sender: TObject);
var i: Integer;
begin
MInfo.Lines.Clear;

MInfo.Lines.Add(Format('There are %d total CPU in your system',[GetCPUCount]));

for i:=0 to GetCPUCount-1 do MInfo.Lines.Add('');
end;

end.


adCpuUsage.pas

unit adCpuUsage;

{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
CPU Usage Measurement routines for Delphi and C++ Builder

Author: Alexey A. Dynnikov
EMail: aldyn@chat.ru
WebSite: http://www.aldyn.ru/
Support: Use the e-mail aldyn@chat.ru
or support@aldyn.ru

Creation: Jul 8, 2000
Version: 1.02

Legal issues: Copyright (C) 2000 by Alexey A. Dynnikov

This software is provided 'as-is', without any express or
implied warranty. In no event will the author be held liable
for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it
and redistribute it freely, subject to the following
restrictions:

1. The origin of this software must not be misrepresented,
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
USAGE:

1. Include this unit into project.

2. Call GetCPUCount to obtain the numbr of processors in the system

3. Each time you need to know the value of CPU usage call the CollectCPUData
to refresh the CPU usage information. Then call the GetCPUUsage to obtain
the CPU usage for given processor. Note that succesive calls of GetCPUUsage
without calling CollectCPUData will return the same CPU usage value.

Example:

procedure TTestForm.TimerTimer(Sender: TObject);
var i: Integer;
begin
CollectCPUData; // Get the data for all processors

for i:=0 to GetCPUCount-1 do // Show data for each processor
MInfo.Lines[i]:=Format('CPU #%d - %5.2f%%',[i,GetCPUUsage(i)*100]);
end;
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}

interface

uses
Windows, SysUtils;

// Call CollectCPUData to refresh information about CPU usage
procedure CollectCPUData;

// Call it to obtain the number of CPU's in the system
function GetCPUCount: Integer;

// Call it to obtain the % of usage for given CPU
function GetCPUUsage(Index: Integer): Double;

// For Win9x only: call it to stop CPU usage monitoring and free system resources
procedure ReleaseCPUData;

implementation

{$ifndef ver110}

{$ifndef ver90}
{$ifndef ver100}
{$define UseInt64}
{$endif}
{$endif}


{$ifdef UseInt64}
type TInt64 = Int64;
{$else}
type TInt64 = Comp;
{$endif}

{$else}

type TInt64 = TLargeInteger;

{$endif}

type
PInt64 = ^TInt64;

type
TPERF_DATA_BLOCK = record
Signature : array[0..4 - 1] of WCHAR;
LittleEndian : DWORD;
Version : DWORD;
Revision : DWORD;
TotalByteLength : DWORD;
HeaderLength : DWORD;
NumObjectTypes : DWORD;
DefaultObject : Longint;
SystemTime : TSystemTime;
Reserved: DWORD;
PerfTime : TInt64;
PerfFreq : TInt64;
PerfTime100nSec : TInt64;
SystemNameLength : DWORD;
SystemNameOffset : DWORD;
end;

PPERF_DATA_BLOCK = ^TPERF_DATA_BLOCK;

TPERF_OBJECT_TYPE = record
TotalByteLength : DWORD;
DefinitionLength : DWORD;
HeaderLength : DWORD;
ObjectNameTitleIndex : DWORD;
ObjectNameTitle : LPWSTR;
ObjectHelpTitleIndex : DWORD;
ObjectHelpTitle : LPWSTR;
DetailLevel : DWORD;
NumCounters : DWORD;
DefaultCounter : Longint;
NumInstances : Longint;
CodePage : DWORD;
PerfTime : TInt64;
PerfFreq : TInt64;
end;

PPERF_OBJECT_TYPE = ^TPERF_OBJECT_TYPE;

type
TPERF_COUNTER_DEFINITION = record
ByteLength : DWORD;
CounterNameTitleIndex : DWORD;
CounterNameTitle : LPWSTR;
CounterHelpTitleIndex : DWORD;
CounterHelpTitle : LPWSTR;
DefaultScale : Longint;
DetailLevel : DWORD;
CounterType : DWORD;
CounterSize : DWORD;
CounterOffset : DWORD;
end;

PPERF_COUNTER_DEFINITION = ^TPERF_COUNTER_DEFINITION;

TPERF_COUNTER_BLOCK = record
ByteLength : DWORD;
end;

PPERF_COUNTER_BLOCK = ^TPERF_COUNTER_BLOCK;

TPERF_INSTANCE_DEFINITION = record
ByteLength : DWORD;
ParentObjectTitleIndex : DWORD;
ParentObjectInstance : DWORD;
UniqueID : Longint;
NameOffset : DWORD;
NameLength : DWORD;
end;

PPERF_INSTANCE_DEFINITION = ^TPERF_INSTANCE_DEFINITION;

//------------------------------------------------------------------------------
{$ifdef ver130}
{$L-} // The L+ causes internal error in Delphi 5 compiler
{$O-} // The O+ causes internal error in Delphi 5 compiler
{$Y-} // The Y+ causes internal error in Delphi 5 compiler
{$endif}

{$ifndef ver110}
type
TInt64F = TInt64;
{$else}
type
TInt64F = Extended;
{$endif}

{$ifdef ver110}
function FInt64(Value: TInt64): TInt64F;
function Int64D(Value: DWORD): TInt64;
{$else}
type
FInt64 = TInt64F;
Int64D = TInt64;
{$endif}

{$ifdef ver110}
function FInt64(Value: TInt64): TInt64F;
var V: TInt64;
begin
if (Value.HighPart and $80000000) = 0 then // positive value
begin
result:=Value.HighPart;
result:=result*$10000*$10000;
result:=result+Value.LowPart;
end else
begin
V.HighPart:=Value.HighPart xor $FFFFFFFF;
V.LowPart:=Value.LowPart xor $FFFFFFFF;
result:= -1 - FInt64(V);
end;
end;

function Int64D(Value: DWORD): TInt64;
begin
result.LowPart:=Value;
result.HighPart := 0; // positive only
end;
{$endif}

//------------------------------------------------------------------------------

const
Processor_IDX_Str = '238';
Processor_IDX = 238;
CPUUsageIDX = 6;

type
AInt64F = array[0..$FFFF] of TInt64F;
PAInt64F = ^AInt64F;

var
_PerfData : PPERF_DATA_BLOCK;
_BufferSize: Integer;
_POT : PPERF_OBJECT_TYPE;
_PCD: PPerf_Counter_Definition;
_ProcessorsCount: Integer;
_Counters: PAInt64F;
_PrevCounters: PAInt64F;
_SysTime: TInt64F;
_PrevSysTime: TInt64F;
_IsWinNT: Boolean;

_W9xCollecting: Boolean;
_W9xCpuUsage: DWORD;
_W9xCpuKey: HKEY;


//------------------------------------------------------------------------------
function GetCPUCount: Integer;
begin
if _IsWinNT then
begin
if _ProcessorsCount < 0 then CollectCPUData;
result:=_ProcessorsCount;
end else
begin
result:=1;
end;

end;

//------------------------------------------------------------------------------
procedure ReleaseCPUData;
var H: HKEY;
R: DWORD;
dwDataSize, dwType: DWORD;
begin
if _IsWinNT then exit;
if not _W9xCollecting then exit;
_W9xCollecting:=False;

RegCloseKey(_W9xCpuKey);

R:=RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats\StopStat', 0, KEY_ALL_ACCESS, H );

if R <> ERROR_SUCCESS then exit;

dwDataSize:=sizeof(DWORD);

RegQueryValueEx ( H, 'KERNEL\CPUUsage', nil, @dwType, PBYTE(@_W9xCpuUsage), @dwDataSize);

RegCloseKey(H);

end;

//------------------------------------------------------------------------------
function GetCPUUsage(Index: Integer): Double;
begin
if _IsWinNT then
begin
if _ProcessorsCount < 0 then CollectCPUData;
if (Index >= _ProcessorsCount) or (Index < 0) then
raise Exception.Create('CPU index out of bounds');
if _PrevSysTime = _SysTime then result:=0 else
result:=1-(_Counters[index] - _PrevCounters[index])/(_SysTime-_PrevSysTime);
end else
begin
if Index <> 0 then
raise Exception.Create('CPU index out of bounds');
if not _W9xCollecting then CollectCPUData;
result:=_W9xCpuUsage / 100;
end;
end;

var VI: TOSVERSIONINFO;

//------------------------------------------------------------------------------
procedure CollectCPUData;
var BS: integer;
i: Integer;
_PCB_Instance: PPERF_COUNTER_BLOCK;
_PID_Instance: PPERF_INSTANCE_DEFINITION;
ST: TFileTime;

var H: HKEY;
R: DWORD;
dwDataSize, dwType: DWORD;
begin
if _IsWinNT then
begin
BS:=_BufferSize;
while RegQueryValueEx( HKEY_PERFORMANCE_DATA, Processor_IDX_Str, nil, nil,
PByte(_PerfData), @BS ) = ERROR_MORE_DATA do
begin
// Get a buffer that is big enough.
INC(_BufferSize,$1000);
BS:=_BufferSize;
ReallocMem( _PerfData, _BufferSize );
end;

// Locate the performance object
_POT := PPERF_OBJECT_TYPE(DWORD(_PerfData) + _PerfData.HeaderLength);
for i := 1 to _PerfData.NumObjectTypes do
begin
if _POT.ObjectNameTitleIndex = Processor_IDX then Break;
_POT := PPERF_OBJECT_TYPE(DWORD(_POT) + _POT.TotalByteLength);
end;

// Check for success
if _POT.ObjectNameTitleIndex <> Processor_IDX then
raise Exception.Create('Unable to locate the "Processor" performance object');

if _ProcessorsCount < 0 then
begin
_ProcessorsCount:=_POT.NumInstances;
GetMem(_Counters,_ProcessorsCount*SizeOf(TInt64));
GetMem(_PrevCounters,_ProcessorsCount*SizeOf(TInt64));
end;

// Locate the "% CPU usage" counter definition
_PCD := PPERF_Counter_DEFINITION(DWORD(_POT) + _POT.HeaderLength);
for i := 1 to _POT.NumCounters do
begin
if _PCD.CounterNameTitleIndex = CPUUsageIDX then break;
_PCD := PPERF_COUNTER_DEFINITION(DWORD(_PCD) + _PCD.ByteLength);
end;

// Check for success
if _PCD.CounterNameTitleIndex <> CPUUsageIDX then
raise Exception.Create('Unable to locate the "% of CPU usage" performance counter');

// Collecting coutners
_PID_Instance := PPERF_INSTANCE_DEFINITION(DWORD(_POT) + _POT.DefinitionLength);
for i := 0 to _ProcessorsCount-1 do
begin
_PCB_Instance := PPERF_COUNTER_BLOCK(DWORD(_PID_Instance) + _PID_Instance.ByteLength );

_PrevCounters[i]:=_Counters[i];
_Counters[i]:=FInt64(PInt64(DWORD(_PCB_Instance) + _PCD.CounterOffset)^);

_PID_Instance := PPERF_INSTANCE_DEFINITION(DWORD(_PCB_Instance) + _PCB_Instance.ByteLength);
end;

_PrevSysTime:=_SysTime;
SystemTimeToFileTime(_PerfData.SystemTime, ST);
_SysTime:=FInt64(TInt64(ST));
end else
begin
if not _W9xCollecting then
begin
R:=RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats\StartStat', 0, KEY_ALL_ACCESS, H );
if R <> ERROR_SUCCESS then
raise Exception.Create('Unable to start performance monitoring');

dwDataSize:=sizeof(DWORD);

RegQueryValueEx( H, 'KERNEL\CPUUsage', nil, @dwType, PBYTE(@_W9xCpuUsage), @dwDataSize );

RegCloseKey(H);

R:=RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats\StatData', 0,KEY_READ, _W9xCpuKey );

if R <> ERROR_SUCCESS then
raise Exception.Create('Unable to read performance data');

_W9xCollecting:=True;
end;

dwDataSize:=sizeof(DWORD);
RegQueryValueEx( _W9xCpuKey, 'KERNEL\CPUUsage', nil,@dwType, PBYTE(@_W9xCpuUsage), @dwDataSize );
end;
end;


initialization
_ProcessorsCount:= -1;
_BufferSize:= $2000;
_PerfData := AllocMem(_BufferSize);

VI.dwOSVersionInfoSize:=SizeOf(VI);
if not GetVersionEx(VI) then raise Exception.Create('Can''t get the Windows version');

_IsWinNT := VI.dwPlatformId = VER_PLATFORM_WIN32_NT;
finalization
ReleaseCPUData;
FreeMem(_PerfData);
end.

星期一, 3月 17, 2008

模擬ListBox按上下鍵會有游標移動的功能

目前尚有問題:未能得知第一個被選的

case TWMKey(Msg).CharCode of
VK_DELETE : BtnRealTimeDelete.Click;

VK_DOWN :
begin
if (LBRealTime.ItemIndex = LBRealTime.Count-1) or (LBRealTime.Count=0) then
exit;
LBRealTime.ItemIndex := LBRealTime.ItemIndex+1;
if GetKeyState(VK_SHIFT) >= 0 then //代表沒按shift
begin
for i:=0 to LBRealTime.Count-1 do
LBRealTime.Selected [i] := false;
g_RealTimeShift := false;
LBRealTime.Selected[LBRealTime.ItemIndex] := true;
end else
begin
for i:=0 to LBRealTime.Count-1 do
LBRealTime.Selected [i] := false;
g_RealTimeShift := true;
if g_RealTimeShiftRec<= LBRealTime.ItemIndex then
for i:=g_RealTimeShiftRec to LBRealTime.ItemIndex do
LBRealTime.Selected [i] := true
else
for i:=g_RealTimeShiftRec downto LBRealTime.ItemIndex do
LBRealTime.Selected [i] := true;
end;
LBRealTimeClick(self);
end;
VK_UP :
begin
if (LBRealTime.ItemIndex = 0) or (LBRealTime.Count=0) then
exit;
LBRealTime.ItemIndex := LBRealTime.ItemIndex-1;
if GetKeyState(VK_SHIFT) >= 0 then //代表沒按shift
begin
for i:=0 to LBRealTime.Count-1 do
LBRealTime.Selected [i] := false;
g_RealTimeShift := false;
LBRealTime.Selected[LBRealTime.ItemIndex] := true;
end else
begin
for i:=0 to LBRealTime.Count-1 do
LBRealTime.Selected [i] := false;
g_RealTimeShift := true;
if g_RealTimeShiftRec<= LBRealTime.ItemIndex then
for i:=g_RealTimeShiftRec to LBRealTime.ItemIndex do
LBRealTime.Selected [i] := true
else
for i:=g_RealTimeShiftRec downto LBRealTime.ItemIndex do
LBRealTime.Selected [i] := true;
end;
LBRealTimeClick(self);
end;

end;

按鍵上下鍵變成下一個物件去


procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case Key of
VK_DOWN: Perform(WM_NEXTDLGCTL, 0, 0);
VK_UP: Perform(WM_NEXTDLGCTL, 1, 0);
end;
end;

星期日, 3月 16, 2008

判斷字串是否為整數

Str:string;
if StrToIntDef(Str,-1)=-1 then
Str 不是數字。

星期一, 3月 10, 2008

取得檔案大小


procedure TForm1.Button1Click(Sender: TObject);
var FileRec:TSearchrec;
begin
FindFirst('C:\blowfish11.rar',faAnyfile,FileRec);
SHOWMESSAGE(INTTOSTR(FILEREC.Size));
FindClose(FileRec);
end;

星期五, 3月 07, 2008

將涵有半型及全型字串轉為全型字串


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

{$R *.dfm}
function AsciiToAlpha(Source: String): String;
const
Alpha: array[32..126] of String = ( ' ', '!', '”','#' ,'$' ,'%','&' ,'’' ,'(' ,')','*','+', ',',
'-', '.', '/', '0', '1', '2', '3', '4', '5', '6','7', '8', '9',
':', ';', '<', '=', '>', '?', '@' , 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J','K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '〔', '\', '〕', '︿','_', '’',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h','i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v','w','x','y','z',
'{', '|', '}', '~'
);
ASCII: array[32..126] of String = (
' ', '!', '"','#' ,'$' ,'%','&' ,'`' ,'(' ,')','*','+', ',',
'-', '.', '/', '0', '1','2', '3', '4', '5', '6','7', '8', '9',
':', ';','<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E','F',
'G', 'H', 'I', 'J','K', 'L', 'M', 'N', 'O','P', 'Q', 'R', 'S',
'T','U', 'V', 'W', 'X', 'Y','Z', '[', '\', ']', '^','_', '`',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x','y','z',
'{', '|', '}', '~'
);
var
w:WideString;
ret:WideString;
i:integer;
begin
w:= Source;
i:=1;
ret := '';
for i := 1 to length(w) do
begin
if w[i] > #128 then
begin
ret := ret+ w[i];
end else begin
if ((Ord(w[i]) >=(32)) and (Ord(w[i])<=(126))) then
begin
ret := ret+ Alpha[ ord(w[i]) ];
end;
end;
end;
result := ret;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
caption := AsciiToAlpha('YAO');
end;

end.

星期二, 3月 04, 2008

使按鈕能有下壓(凹下去)的效果

使用SpeedButton元件,但注意屬性要設定對喔:
AllowAllUp = true;
Down = true;(設定凹下去或凸出來)
GroupIndex = 1;