我是想用CreateProcess运行一个程序,并获得进程Id,然后从这个Id获得程序窗口的句柄,然后修改窗口的标题。可是得到的窗口句柄是错的。
程序中有两处GetWindowThreadProcessId,相同的进程Id竟然对应了不同的窗口句柄。
程序如下。请高手帮我解决。谢谢。unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    Edit3: TEdit;
    Timer1: TTimer;
    ListBox1: TListBox;
    Edit4: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  
//自定义类型
  WNDINFO=packed record
    dwProcessId:DWORD;
    wnd:HWND;
  end;
  LPWNDINFO=^WNDINFO;var
  Form1: TForm1;implementation{$R *.dfm}function YourEnumProc(wnd:HWND; para:LPARAM):BOOL;stdcall;
//枚举窗口的回调函数
var
  dwProcessId:DWORD;
  pInfo:LPWNDINFO;
begin
  GetWindowThreadProcessId(wnd,@dwProcessId);
  pInfo:=LPWNDINFO(para);
  form1.ListBox1.Items.Add(IntToStr(dwProcessId)+' / '+IntToStr(wnd));  
  if dwProcessId=pInfo.dwProcessId then
  begin
    pInfo.wnd:=wnd;
    result:=false;
  end
  else
    result:=true;
end;function GetProcessMainWnd(dwProcessId:DWORD):HWND;
//根据进程ID获取窗口句柄的函数
var
  wi:WNDINFO;
begin
  wi.dwProcessId:=dwProcessId;
  wi.wnd:=HWND(nil);
  EnumWindows(@YourEnumProc,LPARAM(@wi));
  result:=wi.wnd;
end;procedure TForm1.Button1Click(Sender: TObject);
//按钮事件
var
  f:PAnsiChar;
  wnd:HWND;
  len:Integer;
  sz:array[0..255] of Char;
  pi:TProcessInformation;
  si:TStartupInfo;
begin
  ZeroMemory(@sz,256);
  ZeroMemory(@pi,sizeof(pi));
  ZeroMemory(@si,sizeof(si));
  si.lpReserved:=nil;
  si.lpDesktop:=nil;
  si.lpTitle:=nil;
  si.wShowWindow:=SW_SHOWDEFAULT;
  
  f:=@string(Edit1.Text)[1];
  CreateProcess(f,nil, nil, nil,false ,0 ,nil ,nil ,si,pi);
  if WaitForInputIdle(pi.hProcess,INFINITE)=0 then
  begin
    Sleep(2000);
    ListBox1.Clear;
    wnd:=GetProcessMainWnd(pi.dwProcessId);
    len:=GetWindowTextLength(wnd);
    //GetWindowText(wnd,@sz[0],len+1);
    Edit2.Text:=IntToStr(pi.hProcess) + '/' + IntTostr(pi.dwProcessId);
    Edit3.Text:=IntToStr(wnd);
    Edit4.Text:=IntToStr(len);
  end;
end;procedure TForm1.Timer1Timer(Sender: TObject);
//定时获取最前端窗口的进程ID和窗口句柄,用于比较
var
  id:DWORD;
begin
  GetWindowThreadProcessId(GetForegroundWindow(),@id);
  form1.Caption:=IntToStr(id)+' / '+IntTostr(GetForegroundWindow());
end;end.

解决方案 »

  1.   

    程序的主要部分: function YourEnumProc(wnd:HWND; para:LPARAM):BOOL;stdcall;
    //枚举窗口的回调函数
    var
      dwProcessId:DWORD;
      pInfo:LPWNDINFO;
    begin
      GetWindowThreadProcessId(wnd,@dwProcessId);
      pInfo:=LPWNDINFO(para);
      form1.ListBox1.Items.Add(IntToStr(dwProcessId)+' / '+IntToStr(wnd));  
      if dwProcessId=pInfo.dwProcessId then
      begin
        pInfo.wnd:=wnd;
        result:=false;
      end
      else
        result:=true;
    end;function GetProcessMainWnd(dwProcessId:DWORD):HWND;
    //根据进程ID获取窗口句柄的函数
    var
      wi:WNDINFO;
    begin
      wi.dwProcessId:=dwProcessId;
      wi.wnd:=HWND(nil);
      EnumWindows(@YourEnumProc,LPARAM(@wi));
      result:=wi.wnd;
    end;procedure TForm1.Button1Click(Sender: TObject);
    //按钮事件
    var
      f:PAnsiChar;
      wnd:HWND;
      len:Integer;
      sz:array[0..255] of Char;
      pi:TProcessInformation;
      si:TStartupInfo;
    begin
      ZeroMemory(@sz,256);
      ZeroMemory(@pi,sizeof(pi));
      ZeroMemory(@si,sizeof(si));
      si.lpReserved:=nil;
      si.lpDesktop:=nil;
      si.lpTitle:=nil;
      si.wShowWindow:=SW_SHOWDEFAULT;
      
      f:=@string(Edit1.Text)[1];
      CreateProcess(f,nil, nil, nil,false ,0 ,nil ,nil ,si,pi);
      if WaitForInputIdle(pi.hProcess,INFINITE)=0 then
      begin
        Sleep(2000);
        ListBox1.Clear;
        wnd:=GetProcessMainWnd(pi.dwProcessId);
        len:=GetWindowTextLength(wnd);
        //GetWindowText(wnd,@sz[0],len+1);
        Edit2.Text:=IntToStr(pi.hProcess) + '/' + IntTostr(pi.dwProcessId);
        Edit3.Text:=IntToStr(wnd);
        Edit4.Text:=IntToStr(len);
      end;
    end;