2008-3-4 18:55
dwf3110
求一问题
[size=2]在Aimgoo编写的CpuWHelper代码中,有一段程序如下:[/size]
[size=2]function EnumFunc(Handle : HWnd; var PI64 : Int64Rec): Bool; stdcall;
var
_ClassName : array [0..255] of Char;
PID : Cardinal;
begin
Result := True;
PID := 0;
GetWindowThreadProcessId(Handle, @PID);
if PID = PI64.Lo then
begin
GetClassName(Handle, @_ClassName[0], 255);
if StrComp(_ClassName, pChar(PI64.Hi)) = 0 then
begin
PI64.Hi := Handle;
Result := False;
end;
end;
end;[/size]
[size=2]function HwndByClassName(ClassName : String; PID : Integer = 0) : HWND;
var
PI64 : Int64Rec;
begin
if PID = 0 then
PI64.Lo := GetCurrentProcessID
else
PI64.Lo := PID;[/size]
[size=2] PI64.Hi := Integer(pChar(ClassName));
EnumWindows(@EnumFunc, Integer(@PI64));
if [b][u][color=red]PI64.Hi = Cardinal(pChar(ClassName))[/color][/u][/b] then
Result := 0
else
Result := PI64.Hi;
end;[/size]
[size=2][/size]
[size=2]首先确定上面的代码是正确,且可以正常运行;其中红色标注部分另我十分迷惑,请求大家帮忙看看。[/size]
[size=2]自己写了段相比较的代码[/size]
[color=royalblue]function HwndByClassName1(ClassName : String; PID : Integer = 0) : HWND;
var
PI64, PI642 : Int64Rec;
begin
if PID = 0 then
PI64.Lo := GetCurrentProcessID
else
PI64.Lo := PID;[/color]
[color=royalblue] PI64.Hi := Cardinal(pChar(ClassName));
PI642.Hi := Integer(pChar(ClassName));
EnumWindows(@EnumFunc, Integer(@PI64));
PI642.Hi := Cardinal(pChar(ClassName));
if PI642.Hi = Cardinal(pChar(ClassName)) then //PI64.Hi与PI642.Hi不相同;
Result := 0
else
Result := PI64.Hi;
end;[/color]
[color=black]请问[/color][color=black]Cardinal(pChar(ClassName))的工作原理是什么; [/color]
[size=2][/size]
2008-3-5 15:27
Passion
Cardinal(pChar(ClassName))是获得代表其地址的四字节整数吧。
2008-3-5 18:40
dwf3110
回复 #2 Passion 的帖子
从代码的表面上看好象是获得代表其地址的四字节整数;但是如下例子:
function Check( SS: String; P: Int64Rec) : Boolean;
begin
P.Lo := Cardinal(PChar(SS));
P.Hi := Cardinal(PChar(SS));
Result := (P.Lo = Cardinal(PChar(SS))) [color=red] // P.Lo = P.Hi = Cardinal(PChar(SS)))[/color]
end;
function Check1(SS: String; P: Int64Rec) : Boolean;
begin
P.Lo := Cardinal(PChar(SS));
ss := '1';
P.Hi := Cardinal(PChar(SS));
Result := (P.Lo = Cardinal(PChar(SS))) [color=red]//P.Lo <> P.Hi = Cardinal(PChar(SS)))[/color]
end;
procedure TForm1.Button1Click(Sender: TObject);
var
vInt1: Int64Rec;
begin
if Check(Caption, vInt1) then
Showmessage('True')
else
ShowMessage('False');
end;
procedure TForm1.Button2Click(Sender: TObject);
var
vInt1: Int64Rec;
begin
vInt1.Lo := Cardinal(PChar(Caption));
vInt1.Hi := Cardinal(PChar(Caption));
if vInt1.Lo = Cardinal(PChar(Caption)) then [color=red]//P.Lo <> P.Hi <> Cardinal(PChar(Caption)))
[/color] Showmessage('True')
else
ShowMessage('False');
end;
procedure TForm1.Button3Click(Sender: TObject);
var
vInt1: Int64Rec;
begin
if Check1(Caption, vInt1) then
Showmessage('True')
else
ShowMessage('False');
end;
有三种情况出现了。[color=red]([/color][color=red]好象与字符的写复制有关)[/color]
[[i] 本帖最后由 dwf3110 于 2008-3-5 18:42 编辑 [/i]]
2008-3-6 09:54
Rainstorey
Cardinal(pChar(ClassName))
pChar(ClassName);//得到指向ClassName的Char *
Cardinal(char *);//得到指针的地址的Cardinal表示
2008-3-8 16:49
bahamut8348
var
s: string;
begin
s:= '123';
PAnsiChar(s); //把DELPHI字符串转换成WINDOWS字符串, 不管是DELPHI还是WINDOWS的字符串,其实都是指针,指针就是一个4BYTE的数据类型,在C里经常可以看到 (DWORD) ptr这样的语句,其实就是把指针类型转换成数值型,但是值并没有变
而Cardinal(PAnsiChar(s));和(DWORD)ptr这样是等价的,你可以下一个断点,然后用IDE跟踪值看看就知道了
页:
[1]
Powered by Discuz! Archiver 5.0.0
© 2001-2006 Comsenz Inc.