DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: jsuguo
今日帖子: 27
在线用户: 24
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 ltshdp (禁卫军) ▲▲▲△△ -
普通会员
2018/1/23 11:01:37
标题:
已知PID得到窗口句柄编译成64位应用时值为0 浏览:971
加入我的收藏
楼主: 用网上的源程序,编译成32位应用时没问题,64位时值为0。是为什么。
function GetHWndByPID(const hPID: THandle): THandle;
type
PEnumInfo = ^TEnumInfo;
TEnumInfo = record
ProcessID: DWORD;
HWND: THandle;
end;

function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
var
PID: DWORD;
begin
GetWindowThreadProcessID(Wnd, @PID);
Result := (PID <> EI.ProcessID) or
(not IsWindowVisible(WND)) or
(not IsWindowEnabled(WND));

if not Result then EI.HWND := WND;
end;

function FindMainWindow(PID: DWORD): DWORD;
var
EI: TEnumInfo;
begin
EI.ProcessID := PID;
EI.HWND := 0;
EnumWindows(@EnumWindowsProc, Integer(@EI));
Result := EI.HWND;
end;
begin
if hPID<>0 then
Result:=FindMainWindow(hPID)
else
Result:=0;
end;


谢谢!!
----------------------------------------------
-
作者:
男 fxy_2002 (yong) ▲▲▲△△ -
普通会员
2018/1/23 13:21:55
1楼: 网上很多DELPHI代码都有这样那样的问题,很多是WIN32、DELPHI7时代留下来的。我刚好前些天要有这个功能,找到的代码也是WIN64不可用。后来自己改了下就OK了。你试试这段:

//窗体枚举结构
TEnumInfo = record
    ProcessID: DWORD;      //进程ID
    HWND: THandle;         //窗体句柄
    HTHD: THandle;         //窗体线程句柄
    CaptionFlag: array[0..254] of char;    //窗体标题关键字
end;


//通过进程ID枚举找到进程主窗体
//EI:包含进程信息的结构体(可扩展)
function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
var
  PID: DWord;
  h: THandle;
  arr: array[0..254] of Char;
  tmpIsFlag:Boolean;
  tmpThreadID:THandle;
begin
  Result := True;
  tmpThreadID:=GetWindowThreadProcessID(Wnd, @PID);
  if PID = EI.ProcessID then     //是指定进程的窗体
  begin
    h := GetWindowLong(Wnd, GWL_HWNDPARENT);
    if h = 0 then
    begin
      tmpIsFlag:=true;
      if EI.CaptionFlag<>'' then     //需要按标题过滤
      begin
        tmpIsFlag:=false;
        GetWindowText(Wnd,@arr, SizeOf(arr));
        if Pos(EI.CaptionFlag,arr)>0 then    //标题包含指定关键字
          tmpIsFlag:=true;
      end;

      if tmpIsFlag then
      begin
        EI.HWND := Wnd;        //窗体句柄
        EI.HTHD:=tmpThreadID;  //窗体线程句柄
        Result := False;
      end;
    end;
  end;
  if not Result then
    EI.HWND := WND;
end;

//从进程ID获取其窗口句柄
//hPID:进程的PID
//hThreadID:指到窗体的线程句柄(没找到返回0)
//CaptionFlag:窗口标题关键字(可以为空)
//返回值:窗体句柄
function GetHwndFromProcess(const hPID: THandle;var hThreadID:THandle;CaptionFlag:String=''): THandle;

  function FindMainWindow(PID: DWORD;var hThreadID:THandle;CaptionFlag:String=''): DWORD;
  var
    EI: TEnumInfo;
  begin
    EI.ProcessID := PID;
    EI.HWND := 0;
    EI.HTHD:=0;
    StrPCopy(EI.CaptionFlag, CaptionFlag);
    EnumWindows(@EnumWindowsProc, Integer(@EI));
    hThreadID:=EI.HTHD;
    Result := EI.HWND;
  end;

begin
  if hPID <> 0 then
    Result := FindMainWindow(hPID,hThreadID,CaptionFlag)
  else
  begin
    hThreadID:=0;
    Result:=0;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  tmpHand,tmpThrID:THandle;
begin
  tmpHand:=GetHwndFromProcess(StrToInt(edPId.Text),tmpThrID);

  ShowMessage('PID:'+edPId.Text+',窗体句柄:'+IntToStr(tmpHand)+',窗体线程:'+IntToStr(tmpThrID));
end;
此帖子包含附件:
PNG 图像
大小:18.1K
----------------------------------------------
-
作者:
男 ltshdp (禁卫军) ▲▲▲△△ -
普通会员
2018/1/23 16:02:57
2楼: 可用,32位64位应用都可以。谢谢!
还有一个关于32位与64位的问题
IsWow64Process在32位应用程序下可以。在64位编译运行出错,程序直接死了。是为什么?
----------------------------------------------
-
作者:
男 ltshdp (禁卫军) ▲▲▲△△ -
普通会员
2018/1/23 16:20:08
3楼: 找到问题了。
第二个参数32位下可以用Boolean,64位下一定要用bool
----------------------------------------------
-
作者:
男 ltshdp (禁卫军) ▲▲▲△△ -
普通会员
2018/1/23 16:48:11
4楼: 还有一个问题。在进程有多个线程时,得到的窗口句柄不是主窗口句柄。
----------------------------------------------
-
作者:
男 ltshdp (禁卫军) ▲▲▲△△ -
普通会员
2018/1/23 16:56:58
5楼:       if tmpIsFlag then
      begin
        EI.HWND := Wnd;        //窗体句柄
        EI.HTHD:=tmpThreadID;  //窗体线程句柄
        //Result := False;
        Result:=(PID <> EI.ProcessID) or
(not IsWindowVisible(WND)) or
(not IsWindowEnabled(WND));
      end;

这样改就可以了
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行78.125毫秒 RSS