Dll中函数:
procedure Test(App:TApplication);stdcall;
var frm,men:TComponent;
begin
  frm :=App.FindComponent('frmMain');
  if frm<>nil then//***************
  begin
    men :=(frm as TForm).FindComponent('About1');
    if men<>nil then
      (men as TMenuItem).Click;
  end;
end;但是执行到*位置就报错。
我该怎么做呢?

解决方案 »

  1.   

    我试了一下,问题出在
     men :=(frm as TForm).FindComponent('About1');
    虽然能找到 frm ,但不能用frm的FindComponent
      

  2.   

    FindComponent是Find自已拥有的component, 找其它窗体是找不到的.
    源代码很清楚了,可以做为容器的component自己维护着一个list,FindComponent是在List中Find.
      

  3.   

    打印frm的ClassType看看到底是什么
      

  4.   

    你如果把这个dll注入到frmMain所在的进程再调用findcomponent就可以了。
      

  5.   

    procedure FindAProcess(const AFilename: string; const PathMatch: Boolean; var ProcessID: DWORD);
    var
      lppe: TProcessEntry32;
      SsHandle: Thandle;
      FoundAProc, FoundOK: boolean;
    begin
      ProcessID :=0;
      SsHandle := CreateToolHelp32SnapShot(TH32CS_SnapProcess, 0);
      FoundAProc := Process32First(Sshandle, lppe);
      while FoundAProc do
      begin
        if PathMatch then
          FoundOK := AnsiStricomp(lppe.szExefile, PChar(AFilename)) = 0
        else
          FoundOK := AnsiStricomp(PChar(ExtractFilename(lppe.szExefile)), PChar(ExtractFilename(AFilename))) = 0;
        if FoundOK then
        begin
          ProcessID := lppe.th32ProcessID;
          break;
        end;
        FoundAProc := Process32Next(SsHandle, lppe);
      end;
      CloseHandle(SsHandle);
    end;function EnabledDebugPrivilege(const bEnabled: Boolean): Boolean;
    var
      hToken: THandle;
      tp: TOKEN_PRIVILEGES;
      a: DWORD;
    const
      SE_DEBUG_NAME = 'SeDebugPrivilege';
    begin
      Result := False;
      if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken)) then
      begin
        tp.PrivilegeCount := 1;
        LookupPrivilegeValue(nil, SE_DEBUG_NAME, tp.Privileges[0].Luid);
        if bEnabled then
          tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
        else
          tp.Privileges[0].Attributes := 0;
        a := 0;
        AdjustTokenPrivileges(hToken, False, tp, SizeOf(tp), nil, a);
        Result := GetLastError = ERROR_SUCCESS;
        CloseHandle(hToken);
      end;
    end;function AttachToProcess(const HostFile, GuestFile: string; const PID: DWORD = 0): DWORD;
    var
      hRemoteProcess: THandle;
      dwRemoteProcessId: DWORD;
      cb: DWORD;
      pszLibFileRemote: Pointer;
      iReturnCode: Boolean;
      TempVar: DWORD;
      pfnStartAddr: TFNThreadStartRoutine;
      pszLibAFilename: PwideChar;
    begin
      Result := 0;
      EnabledDebugPrivilege(True);
      Getmem(pszLibAFilename, Length(GuestFile) * 2 + 1);
      StringToWideChar(GuestFile, pszLibAFilename, Length(GuestFile) * 2 + 1);
      if PID > 0 then
         dwRemoteProcessID := PID
      else
         FindAProcess(HostFile, False, dwRemoteProcessID);
      hRemoteProcess := OpenProcess(PROCESS_CREATE_THREAD + {允许远程创建线程}
          PROCESS_VM_OPERATION + {允许远程VM操作}
          PROCESS_VM_WRITE, {允许远程VM写}
          FALSE, dwRemoteProcessId);
      cb := (1 + lstrlenW(pszLibAFilename)) * sizeof(WCHAR);
      pszLibFileRemote := PWIDESTRING(VirtualAllocEx(hRemoteProcess, nil, cb, MEM_COMMIT, PAGE_READWRITE));
      TempVar := 0;
      iReturnCode := WriteProcessMemory(hRemoteProcess, pszLibFileRemote, pszLibAFilename, cb, TempVar);
      if iReturnCode then
      begin
        pfnStartAddr := GetProcAddress(GetModuleHandle('Kernel32'), 'LoadLibraryW');
        TempVar := 0;
        Result := CreateRemoteThread(hRemoteProcess, nil, 0, pfnStartAddr, pszLibFileRemote, 0, TempVar);
      end;
      Freemem(pszLibAFilename);
    end;用AttachToProcess('a.exe','c:\a.dll',0)就可以把a.dll注入到a.exe中去了