function FindControl(Handle: HWnd): TWinControl;
var
  OwningProcess: DWORD;
begin
  Result := nil;
  if (Handle <> 0) and (GetWindowThreadProcessID(Handle, OwningProcess) <> 0) and
     (OwningProcess = GetCurrentProcessId) then
  begin
    if GlobalFindAtom(PChar(ControlAtomString)) = ControlAtom then
      Result := Pointer(GetProp(Handle, MakeIntAtom(ControlAtom)))
    else
      Result := ObjectFromHWnd(Handle);
  end;
end;//经过窗体测试和DLL测试以下代码也可以正常工作,请各位前辈指导!谢谢!
function FindControl(Handle: HWnd): TWinControl;
var
  OwningProcess: DWORD;
begin
  Result := nil;
  if (Handle <> 0) and (GetWindowThreadProcessID(Handle, OwningProcess) <> 0) and
     (OwningProcess = GetCurrentProcessId) then
  begin
      Result := ObjectFromHWnd(Handle); //有这一句不就足矣了吗,怎么还要Result := Pointer(GetProp(Handle, MakeIntAtom(ControlAtom)))
  //很不解,请前辈指导!谢谢!
  end;
end;

解决方案 »

  1.   

    主程序和dll的地址空间并不一致。
    实例句柄(hInstance)也不同,ControlAtomString也不同,所以需要
    if GlobalFindAtom(PChar(ControlAtomString)) = ControlAtom then
    以确保找到的是同一地址空间的东西。
      

  2.   

    但我改后的代码在DLL空间也能正常运行?
      

  3.   

    我是如下改的
    function FindControl1(Handle: HWnd): TWinControl;
    var
      OwningProcess: DWORD;
      ControlAtomString :string;
      ControlAtom :TAtom;
      RM_GetObjectInstance : dword;
    begin
      ControlAtomString := Format('ControlOfs%.8X%.8X', [HInstance, GetCurrentThreadID]);
      ControlAtom := GlobalAddAtom(PChar(ControlAtomString));
      RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));
      Result := nil;
      if (Handle <> 0) and (GetWindowThreadProcessID(Handle, OwningProcess) <> 0) and
         (OwningProcess = GetCurrentProcessId) then
      begin
        Result := Pointer(SendMessage(Handle, RM_GetObjectInstance, 0, 0));
        {if GlobalFindAtom(PChar(ControlAtomString+'x')) = ControlAtom then
          Result := Pointer(GetProp(Handle, MakeIntAtom(ControlAtom)))
        else
           Result := Pointer(SendMessage(Handle, RM_GetObjectInstance, 0, 0));
           ShowMessage(IntToStr(Integer(Result)));  }
      end;
    end;