Board logo

Subject: 求一问题 [Print This Page]

Author: dwf3110    Time: 2008-3-4 18:55     Subject: 求一问题

在Aimgoo编写的CpuWHelper代码中,有一段程序如下:
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;


function HwndByClassName(ClassName : String; PID : Integer = 0) : HWND;
var
  PI64 : Int64Rec;
begin
  if PID = 0 then
    PI64.Lo := GetCurrentProcessID
  else
    PI64.Lo := PID;


  PI64.Hi := Integer(pChar(ClassName));
  EnumWindows(@EnumFunc, Integer(@PI64));   
  if PI64.Hi = Cardinal(pChar(ClassName)) then  
    Result := 0
  else
    Result := PI64.Hi;
end;


首先确定上面的代码是正确,且可以正常运行;其中红色标注部分另我十分迷惑,请求大家帮忙看看。
自己写了段相比较的代码
function HwndByClassName1(ClassName : String; PID : Integer = 0) : HWND;
var
  PI64, PI642 : Int64Rec;
begin
  if PID = 0 then
    PI64.Lo := GetCurrentProcessID
  else
    PI64.Lo := PID;

  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;

请问Cardinal(pChar(ClassName))的工作原理是什么;

Author: Passion    Time: 2008-3-5 15:27

Cardinal(pChar(ClassName))是获得代表其地址的四字节整数吧。
Author: dwf3110    Time: 2008-3-5 18:40     Subject: 回复 #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)))        // P.Lo =  P.Hi = Cardinal(PChar(SS)))     
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)))    //P.Lo <>  P.Hi = Cardinal(PChar(SS)))   
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  //P.Lo <>  P.Hi <> Cardinal(PChar(Caption)))
    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;
有三种情况出现了。好象与字符的写复制有关)

[ 本帖最后由 dwf3110 于 2008-3-5 18:42 编辑 ]
Author: Rainstorey    Time: 2008-3-6 09:54

Cardinal(pChar(ClassName))
pChar(ClassName);//得到指向ClassName的Char *
Cardinal(char *);//得到指针的地址的Cardinal表示
Author: bahamut8348    Time: 2008-3-8 16:49

var
  s: string;
begin
  s:= '123';
  PAnsiChar(s); //把DELPHI字符串转换成WINDOWS字符串, 不管是DELPHI还是WINDOWS的字符串,其实都是指针,指针就是一个4BYTE的数据类型,在C里经常可以看到 (DWORD) ptr这样的语句,其实就是把指针类型转换成数值型,但是值并没有变
  而Cardinal(PAnsiChar(s));和(DWORD)ptr这样是等价的,你可以下一个断点,然后用IDE跟踪值看看就知道了




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0