星期五, 1月 18, 2008

取得目前(所有)的螢幕解析度及色彩

目前

procedure TForm1.Button1Click(Sender: TObject);
var
dm: TDeviceMode;
Mode: string;
begin
Memo1.Clear;
Mode := '';

EnumDisplaySettings(nil, High(DWORD)-1, dm);
Mode := IntToStr(dm.dmBitsPerPel) + ' Bits Per Pixel ' +
IntToStr(dm.dmPelsWidth) + ' x ' +
IntToStr(dm.dmPelsHeight);
memo1.lines.Add(Mode);
end;



procedure GetVideoModes(ModeList: TStrings);
var
i, j: integer;
MoreModes,
AddMode: boolean;
dm: TDeviceMode;
Mode: string;
begin
ModeList.Clear;
MoreModes := True;
Mode := '';
i := 0;
while MoreModes do
begin
MoreModes := EnumDisplaySettings(nil, i, dm);
Mode := IntToStr(dm.dmBitsPerPel) + ' Bits Per Pixel ' +
IntToStr(dm.dmPelsWidth) + ' x ' +
IntToStr(dm.dmPelsHeight);
AddMode := True;
{ Check to make sure this mode is not already in the list. }
for j := 0 to ModeList.Count-1 do
if Mode = ModeList[j] then
AddMode := False;
if AddMode then
ModeList.Add(Mode);
Inc(i);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
GetVideoModes(memo1.lines);
end;

星期四, 1月 17, 2008

使用一個隱藏視窗在跑Timer

Unit1.pas
新增2個按鈕,並在入事件

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ApplicationEvents1: TApplicationEvents;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
AAInit;
g_AA.TestHD:=Self.Handle;
end;

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

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if Msg.message = WM_USER + 22 then
begin
Self.Caption:=IntToStr(Msg.wParam);
end;
end;

end.

UnitTAA.pas

unit UnitTAA;

interface

uses Windows, SysUtils, Classes, Graphics, ExtCtrls, Messages, UnitCommon;

const
TimerID_15 = 11111;

type
TAA = class(TObject)
private
{ Private declarations }
MyWinClass : TWndClass;
FMyHideHD : THandle;
FTestHd : THandle;
procedure Init;
public
{ Public declarations }
property MyHideHD : THandle read FMyHideHD;
property TestHD : THandle read FTestHD write FTestHd;
constructor Create;
destructor Destroy;
procedure OnTimer();
end;

procedure AAInit();

var
g_AA : TAA;

implementation

{ TAA }

function TAAWindowProc(hWnd:HWND; iMsg:Integer; wParam:WPARAM; lParam:LPARAM): Integer; stdcall;
var
uTimer : DWORD;
begin
Result:=0;
case iMsg of
WM_CREATE :
begin
uTimer:=SetTimer(hWnd,TimerID_15,1000,nil); //hWnd控制的把柄 TimerId_15標誌 nil指WM_TIMER將處理消息
//if(uTimer = 0) then
// Result:=-1;
exit;
end;
WM_DESTROY :
begin
KillTimer(hWnd, TimerID_15); //銷毀SetTimer建立的計時器
PostQuitMessage(0); //跟Windows說我要退出囉。
exit;
end;
WM_TIMER :
begin
g_AA.OnTimer();
exit;
end;
end;

Result := DefWindowProc(hWnd,iMsg,wParam,lParam); //不感興趣的消息,由windows去處理
end;


constructor TAA.Create;
var
uTimer : DWORD;
begin
DebugStr('TAA.Create');
inherited;
Init;
if IsWindow(FMyHideHD) then
begin
uTimer:=SetTimer(FMyHideHD,TimerID_15,1000,nil);
DebugStr('uTimer = ' + IntToStr(uTimer));
end;
end;

destructor TAA.Destroy;
begin
inherited;
if FMyHideHD <> 0 then
begin
KillTimer(FMyHideHD,TimerID_15);
DestroyWindow(FMyHideHD);
FMyHideHD:=0;
end;
end;

procedure TAA.Init;
var
TempClass : TWndClass;
ClassRegistered : Boolean;
begin
if IsWindow(FMyHideHD) then //檢查MyHD是否為有效的視窗代碼
exit;

try
MyWinClass.style := 0;
MyWinClass.lpfnWndProc := @TAAWindowProc;
MyWinClass.cbClsExtra := 0;
MyWinClass.cbWndExtra := SizeOf(Pointer);
MyWinClass.hInstance := 0;
MyWinClass.hIcon := 0;
MyWinClass.hCursor := 0;
MyWinClass.hbrBackground := 0;
MyWinClass.lpszMenuName := nil;
MyWinClass.lpszClassName := 'MyTAA';
MyWinClass.hInstance := HInstance;
ClassRegistered:=GetClassInfo( HInstance,
MyWinClass.lpszClassName,
TempClass);
//如果沒有存在此class 註冊一個
if not ClassRegistered then
begin
if Windows.RegisterClass(MyWinClass) = 0 then
Exit;
end;

FMyHideHD := CreateWindowEx( WS_EX_TOOLWINDOW,
MyWinClass.lpszClassName,
'', { Window name }
WS_POPUP, { Window Style }
0, 0, { X, Y }
0, 0, { Width, Height }
0, { hWndParent }
0, { hMenu }
HInstance, { hInstance }
nil); { CreateParam }
except
end;
end;

procedure TAA.OnTimer();
var
t : DWORD;
begin
DebugStr('TAA.OnTimer');
t := Random(1000);
PostMessage(g_AA.FTestHd, WM_USER + 22, t, 0);
end;

procedure AAInit();
begin
DebugStr('AAInit');
g_AA := TAA.Create();
end;
end.

記錄Log的pos檔 for DebugView觀看

將UnitCommon.pas程式碼加到入的專案中。

unit UnitCommon;

interface

uses Windows, Forms, SysUtils, Dialogs;
{
const
LOG_LEVEL_HIGH = 1;
LOG_LEVEL_NONE = 0;
}
var
//g_loglevel : integer;
//Buf : array[1..MAX_PATH] of char ;
g_sTempPath : string; // (TempPath)
g_sWorkPath : string; // (WorkingPath)
g_sLogFile : string;
m_create_txt : textFile;
function GetWorkDirectory :String;
function GetTmpDirectory() : string;

procedure DebugStr(sMsg : string);
procedure LogToFile(s:string);

//function GetUserInfoForTest(var sInfo:string) : boolean;

implementation

function GetWorkDirectory;
var
aBuf : array[0..260] of Char;
begin
GetModuleFileName(HINSTANCE, @aBuf[0], SizeOf(aBuf));
Result := IncludeTrailingBackslash(ExtractFilePath(StrPas(aBuf)));
end;

function GetTmpDirectory(): string;
var
dwBuffSize : DWORD;
cBuffer : array[0..MAX_PATH] of char;
begin
dwBuffSize := MAX_PATH;
GetTempPath(dwBuffSize, cBuffer);
Result := cBuffer;
end;
{
//---------------------------------------------------------

procedure ReportLog(str: string);
begin
if(not Assigned(m_Report)) then
Exit;
m_Report.Add(FormatDateTime('yyyy"/"mm"/"dd" "hh:nn:ss ', Now())+str);
end;
//---------------------------------------------------------

procedure ReportLog(str: string; Args: array of const);
var
buf: string;
begin
//Format string.
buf:=Format(str, Args);
//Put Log to Log Factory.
ReportLog(buf);
end;
//---------------------------------------------------------
}

procedure DebugStr(sMsg : string) ;
begin
OutputDebugString(PChar(sMsg));
{
if g_loglevel = LOG_LEVEL_HIGH then
begin
OutputDebugString(PChar(sMsg));
LogToFile(g_sLogFile) ;
end ;
}
end;

procedure LogToFile(s:string) ;
var
txt : textFile;
begin
if g_sLogFile='' then
exit;
try
AssignFile(txt,g_sLogFile);

Append(txt);
writeln(txt,formatDateTime('yyyy/mm/dd hh:nn:ss.zzz',now),' ',s);
CloseFile(txt);
except
g_sLogFile:='';
end;
end;


{
function GetUserInfoForTest(var sInfo:string): boolean;
var
hOpenMap : THandle;
pAddr : pchar;
begin
Result := false;
hOpenMap := OpenFileMapping(
FILE_MAP_READ,
False,
'MyFileMappingObject');

if (GetLastError = ERROR_FILE_NOT_FOUND) then
exit;

pAddr := nil;
try
pAddr := MapViewOfFile(hOpenMap, FILE_MAP_READ, 0, 0, 0);

if (pAddr<>nil) then
begin
sInfo := pAddr;
Result := true;
end;

finally
UnmapViewOfFile(pAddr);
CloseHandle(hOpenMap);
end;
end;
}
initialization
begin
g_sWorkPath:=GetWorkDirectory();
g_sTempPath:=GetTmpDirectory();
createdir(g_sTempPath+'CapScreen'); //在%temp%\下建立QooFunds資料夾
g_sTempPath:=g_sTempPath + 'CapScreen\';
g_sLogFile := g_sTempPath+'Log.txt';


if not FileExists(g_sLogFile) then //不存在,重寫
begin
AssignFile(m_create_txt,g_sLogFile);
ReWrite(m_create_txt);
CloseFile(m_create_txt);
end;


{
g_sTempDir := '' ; g_sLogFile := '' ; fillchar( Buf, MAX_PATH, #0) ;
GetTempPath(MAX_PATH, @Buf[1]) ;
g_sTempDir := Buf;
if g_sTempDir[Length(g_sTempDir)-1] <> '\' then
g_sTempDir := g_sTempDir + '\' ;

g_loglevel := LOG_LEVEL_NONE ;
g_sLogFile := g_sTempDir+'\xtlog.txt' ;
DebugStr( format('XT Temp File: %s', [g_sLogFile]) ) ;
if FileExists(g_sLogFile) then
g_loglevel := LOG_LEVEL_HIGH ;
}
end;

end.

觀看時使用以下程式碼,加到須要顯示之處

DebugStr('AAInit');
LogToFile('AAInit');

星期二, 1月 08, 2008

將CRC寫入檔頭程式碼


unit Unit1;

interface

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

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

type
DWordA =array [0..13059] of DWord;
WordA =array [0..32766] of word;
ByteA =array [0..65534] of byte;
DWordP =^DWordA;
WordP =^WordA;
ByteP =^ByteA;

var
Form1: TForm1;

implementation

{$R *.dfm}
var CRC32T:array[0..255] of DWord;
//==========================================================================
procedure MakeCRC32;
var i,j:Word;
R:DWord;
begin
for i:=0 to 255 do begin
R:=i;
for j:=8 downto 1 do
if (R and 1)>0 then R:=(R shr 1) xor $EDB88320 else R:=R shr 1;
CRC32T[i]:=R;
end;
end;

//==========================================================================
function CRC32(K,D:DWord):DWord;
begin
Result:=CRC32T[byte(K xor DWord(D))] xor (K shr 8);
end;

//==========================================================================
function CalcCRC(P:ByteP; Len:Integer; CRC:DWord):DWord;
var i:integer;
begin
for i:=0 to Len-1 do CRC:=CRC32(CRC,P[i]);
Result:=CRC;
end;

//==========================================================================
function FileCRC32(N:string):DWord;
const _Start=$40;
var Hd:integer;
P:ByteP;
L:DWord;
begin
Result:=0;
if FileExists(N) then begin
Hd:=FileOpen(N,fmOpenRead+fmShareDenyNone);
if Hd>0 then begin
L:=FileSeek(Hd,0,2); FileSeek(Hd,0,0);
GetMem(P,L);
if (L>_Start) and (DWord(FileRead(Hd,P^,L))=L) then
Result:=CalcCRC(@P[_Start],L-_Start,$FFFFFFFF);
FreeMem(P);
FileClose(Hd);
end;
end;
end;

//==========================================================================
function UpdateCRC32(N:string; Chk:DWord):boolean; // Write CRC to file
const _Start=$40;
var Hd,i:integer;
D,R:array[0..7] of byte; // $1E
begin
Result:=False;
DWordP(@D[2])[0]:=Chk; //20處開始由低位元塞CRC資料 若為DWordP(@D[3])[0] 則是從21處開始塞
if FileExists(N) then begin
Hd:=FileOpen(N,fmOpenReadWrite); //開啟N
FileSeek(Hd,$1E,0); FileWrite(Hd,D[0],8); //從1E開始
FileSeek(Hd,$1E,0); FileRead(Hd,R[0],8);

Result:=TRUE;
for i:=0 to SizeOf(D)-1 do if D[i]<>R[i] then Result:=False;
FileClose(Hd);
//end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var S:string;
Result:integer;
Chk,HChk:DWord;
begin
Result:=0; Chk:=0;
if ParamCount>=1 then begin
S:=ParamStr(1); //參數1為檔名
if FileExists(S) then begin
Result:=1; //傳回結果1
MakeCRC32; // Initialize CRC32初始化
Chk :=FileCRC32(S); // Calc CRC32 存於Chk中
if ParamCount=2 then begin //參數2為U UpdateCRC32成功傳回結果2,否則傳回3
if (ParamStr(2)='U') and UpdateCRC32(S,Chk) then Result:=2
else Result:=3;
end
end;
end;
case Result of
0: begin
showmessage('CalcCRC32, Fineart Technology Co., LTD');
showmessage('Ex: ['+ParamStr(0)+'] SourceFile [U]');
end;
1: showmessage(Format('%s CRC32=[%x]',[S,Chk]));
2: showmessage(Format('%s CRC32=[%x] Update!',[S,Chk]));
3: showmessage(Format('%s Update failure!',[S]));
end;
end;
end.