用hook取得外部程序的一个form的句柄后,再获取form的实例,然后可以用Components[I]).Caption的形式来得到form上的label的值,但是如果要获取的是“stringgrid”之类的控件的某单元格的值,用Components[I]).Cell[x,y],编译时就会产生错误。貌似只能获取常用的几个属性值,如caption或者name等,其他控件专用的属性值就无法获取。不知道遇到这样的问题该如何解决,还请高手指点。

解决方案 »

  1.   

    谢谢bdmh,我试一下看看 :)
      

  2.   

    编译有错误,undeclared identifier:'TSringGrid'; 估计TSringGrid不是标准的windows组件,而是delphi自己的。另外form上还有一些文字无法获取,估计这些文字是画上去的,而不是用label形式,对于这些画上去的文字,有什么办法获取吗?
      

  3.   


    if Components[i] is TStringGrid then begin
      TStringGrid(Components[I]).Cell[x,y]  // 這樣來取
    end;
      

  4.   

    if Components[i] is TStringGrid then 
      (Components[I] as TStringGrid).Cell[x,y];
      

  5.   

    谢谢上面几位老师的帮助,只是我在代码中写成:QuotedStr(TStringGrid(vWinControl.Components[I]).Cell[2,2]); 却还是提示错误:undeclared identifier:'Cell';   另外这段代码是在dll中的,部分代码如下:
    function SnifferProc(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT; stdcall;
    var
      vWinControl: TWinControl;
      vCopyDataStruct: TCopyDataStruct;
      I: Integer;
      S: string;
    begin
      case code of
        HC_ACTION:
          begin
            if PCWPStruct(lParam)^.message = WM_SNIFFWINDOW then
            begin
              if ControlAtomString = '' then
              begin
                ControlAtomString := Format('ControlOfs%.8X%.8X', [
                  GetWindowLong(vSnifferInfo^.rHandle, GWL_HINSTANCE),
                  GetWindowThreadProcessId(vSnifferInfo^.rHandle)]);
                ControlAtom := GlobalAddAtom(PChar(ControlAtomString));
                RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));
              end;
              vWinControl := FindControl(vSnifferInfo^.rHandle);
              if Assigned(vWinControl) then
              begin
                for I := 0 to vWinControl.ComponentCount - 1 do
                begin
                  S := '';
                  if SameText(vWinControl.Components[I].ClassName, 'TLabel') then
                  begin
                    S := Format('%s: %s', [vWinControl.Components[I].Name,
                      QuotedStr(TLabel(vWinControl.Components[I]).Caption)]);
                  end else if SameText(vWinControl.Components[I].ClassName, 'TStringGrid') then
                  begin
                    S := Format('%s: %s', [vWinControl.Components[I].Name,
                      QuotedStr(TStringGrid(vWinControl.Components[I]).Cell[2,2])]);
                  end;
                  vCopyDataStruct.cbData := Length(S);
                  vCopyDataStruct.dwData := 0;
                  vCopyDataStruct.lpData := @S[1];
                  SendMessage(vSnifferInfo^.rParam, WM_COPYDATA,
                    vSnifferInfo^.rHandle, Integer(@vCopyDataStruct));
                end;
              end;
            end;
          end;
      end;
      Result := CallNextHookEx(vSnifferInfo^.rHOOK, code, wParam, lParam);
    end;
      

  6.   

    应该是TStringGrid(vWinControl.Components[I]).Cells,加s
      

  7.   

    谢谢,总算编译通过了,不过还是取不到cell里面的值。用这个程序,要获取外部程序中的label的值,还是很有用处的。但是如果对于mdi程序,或者类似StringGrid这样的控件,就好像不管用了,不知道是思路不对,还是我的代码编写有问题
      

  8.   

    对了,再向bdmh请教一下,对于普通外部程序来说,只要获取主窗体的句柄,就可以用这个程序来得到外部程序中所有label值,不用考虑层次关系。但是如果外部程序是个mdi程序,我就不知道怎么处理了,不管是用主窗体的句柄,还是mdi子窗体的句柄,都无法获取,不知道是什么原因啊?
      

  9.   

    网上有用hook跨进程取控件的文章,你可以去看看在zswang(伴水)的博客中也有例子
    http://blog.csdn.net/zswang
      

  10.   

    这个程序本来就是zswang编写的,我再去看看吧。对这些东西接触不多,还是个新手,只希望能得到些思路上的帮助,谢谢bdmh了