我是想用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.
程序中有两处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.
解决方案 »
- XE2中怎样把indy加到Tool Palette中?
- DBGridEh如何让程序更改某一列是否显示
- 如何在select语句的where条件中应用edit的输入?
- 老大们,问个很简单的问题,在线等候!
- 请问哪一位有Turbo pascal2.0,我在做些研究,急用2.0版,其他版没有我要的功能,谢谢!
- 全局变量在另一个单元中读出全部是0的问题。
- delphi6+idl corba+ado出错的问题
- 如何查看机器中的ado版本?
- Delphi 中有没有类似java中stringbuffer的东西。
- 请各位谈谈TACTIONLIST的用法,最好有实例。
- cxgrid数据集无法同步更新?
- 一个菜鸟的问题,求各位大哥大姐帮帮 忙!!!
//枚举窗口的回调函数
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;