不是很难,关于进程句柄的问题(20分)

  • 主题发起人 主题发起人 wp231957
  • 开始时间 开始时间
W

wp231957

Unregistered / Unconfirmed
GUEST, unregistred user!
//扫描顶层窗口===有标题栏
//这是一个回调函数,问题见下面
function enumchildproc4(h:hwnd;l:lparam):dword;stdcall;
var
s,t:array[0..30] of char;
hprocess,processid:dword;
ListItem: TListItem;
lpm:array[0..255] of dword;
mbneed:dword;
lpfilename:string;
begin
getwindowtext(h,@t,30);
getclassname(h,@s,30);
setlength(lpfilename,512);
if t<>'' then begin
getwindowthreadprocessid(h,processid);
// ¸ù¾Ý½ø³ÌID»ñÈ¡¾ä±ú
hprocess:=OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,FALSE,processid);
//ö¾ÙÄ£¿é
enumprocessmodules(hprocess,@lpm,sizeof(lpm),mbneed);
//»ñÈ¡Ê×Ä£¿éµÄÃû×Ö----¸Ã½ø³ÌµÄȫ·¾¶Ãû³Æ
getmodulebasename(hprocess,lpm[0],pchar(lpfilename),512);
listitem:=form1.ListView1.items.Add ;
listitem.Caption :=inttostr(i);
listitem.SubItems.add(s);
listitem.SubItems.add(t);
listitem.SubItems.add(lpfilename);
listitem.SubItems.add(inttostr(processid));//当进程相同时,进程ID也相同
                       //理论上句柄也应该相同,可是就是不同,不知道为什么
listitem.SubItems.add(inttostr(hprocess));
listitem.SubItems.add(inttostr(h));
inc(i);
closehandle(hprocess);  //如果不加这个语句,那么所获取的进程句柄都不相同
               //如果加这个语句,那么所得到的句柄始终都是一个数值
end;
end;
 
进程ID不可能相同,句柄也不会相同,就你运行两次同一个应用程序,那么系统如何知道你正在操作的是哪个呢?就是从句柄上来判断的。
因为理论上你不可能在同一时间运行多个相同的程序。
 
在MSDN上有这样一句话:
Windows 给每个窗口一个唯一的句柄,通过句柄操纵该窗口
 
>>>进程ID不可能相同,句柄也不会相同,就你运行两次同一个应用程序,那么系统如何知>>>道你正在操作的是哪个呢?就是从句柄上来判断的。
>>>因为理论上你不可能在同一时间运行多个相同的程序。

某个进程可能拥有很多个顶层窗口,那么这些顶层窗口所属的进程ID和进程句柄应该是相同的



>>>在MSDN上有这样一句话:
>>>Windows 给每个窗口一个唯一的句柄,通过句柄操纵该窗口

您说的是窗口句柄,而我问的是进程句柄,谢谢
 
不好意思哦,我还没有学到这里来,真的不好意思,我将关注此贴,好好学习一下,你要是找到问题所在,请贴出来让大家看看。
 
难道都看重分分吗

解决可以加分
 
uses TlHelp32

//---窗体遍历回调函数-- {--窗口句柄--} {--额外参数--}
function EnumWindowsProc(WinHwnd: LongWord; Param: LongWord): Boolean; stdcall;
var
WindowText : string ; // 窗体标题
WindowClass : string ; // 窗体类名

WinThreadID : LongWord; // 线程ID
WinProcessId : LongWord; // 进程ID

ModuleStruct : TMODULEENTRY32; // 模块信息结构
ModuleHandle : LongWord; // 快照句柄
FoundModule : Boolean ; // 是否找到模块

MFileName : string ; // 文件名
begin
{--继续遍历--}
Result := TRUE;
{--过滤条件--}
if ( IsWindowVisible(WinHwnd) or IsIconic(WinHwnd) ) and
(
(GetWindowLong(WinHwnd, GWL_HWNDPARENT) = 0) or
(GetWindowLong(WinHwnd, GWL_HWNDPARENT) = Longint(GetDesktopWindow))
)and
( GetWindowLong(WinHwnd, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = 0 ) then
begin
{-----标题文字------}
SetLength(WindowText, GetWindowTextLength(WinHwnd)+2);
Getwindowtext(WinHwnd, Pchar(WindowText), GetWindowTextLength(WinHwnd)+2);
WindowText := string( Pchar(WindowText) );
{-----窗体类名------}
SetLength(WindowClass, 512);
GetClassName(WinHwnd, Pchar(WindowClass), 512);
WindowClass := string( Pchar(WindowClass) );
{----线程&进程ID----}
WinThreadID := GetWindowThreadProcessId(WinHwnd, @WinProcessId);

{---模块列表快照----}
ModuleHandle := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, WinProcessId);
ModuleStruct.dwSize := sizeof(ModuleStruct);
{-----第1个模块-----}
FoundModule := Module32First(ModuleHandle, ModuleStruct);
while (FoundModule) do
begin
MFileName := UpperCase(ExtractFileName(ModuleStruct.szExePath));
{----过滤----}
{ if (MFileName='xx.EXE') or (MFileName='yy.EXE') then
Break else
begin }
form1.Memo1.Lines.Add(Pchar(WindowText));
form1.ListBox1.Items.Add(inttostr(WinHwnd));
// PostMessage(WinHwnd,WM_QUIT,0,0);
Break;
// end;
{----下一个模块----}
FoundModule := Module32Next(ModuleHandle, ModuleStruct);
end;
{----释放句柄----}
CloseHandle(ModuleHandle);
end;
end;


调用
EnumWindows(@EnumWindowsProc,0);
 
接受答案了.
 
后退
顶部