文档章节

详解 EnumWindows 与 EnumWindowsProc - 回复 "SplendourChiang" 的问题

涂孟超
 涂孟超
发布于 2014/09/26 15:35
字数 705
阅读 10
收藏 0
点赞 0
评论 0

问题来源: http://www.cnblogs.com/del/archive/2009/10/16/1584488.html#1727205

// EnumWindows 的功能是遍历所有顶层窗口
function EnumWindows(
  lpEnumFunc: TFNWndEnumProc; {回调函数指针}
  lParam: LPARAM              {给回调函数的参数, 它对应回调函数的第二个参数}
): BOOL; stdcall; //成功与否, 其实是返回了回调函数的返回值

// EnumWindows 专用的回调函数的格式:
function EnumWindowsProc(
  hwnd: HWND;        {找到的窗口句柄}
  lParam: LPARAM     {EnumWindows 传给的参数; 因为它是指针, 可传入, 但一般用作传出数据}
): Boolean; stdcall; {函数返回 False 时, 调用它的 EnumWindows 将停止遍历并返回 False}

 
 
 
 
 

 

 

  

例一: 获取所有顶层窗口的句柄

//需要个 TListBox 显示数据
function EnumWindowsProc_1(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
begin
  Form1.ListBox1.Items.Add(IntToStr(hwnd));
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  EnumWindows(@EnumWindowsProc_1, 0);
end;

 
 
 
 
 

 

 

  

例二: 获取所有顶层窗口的标题(排除无标题窗口)

function EnumWindowsProc_2(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
var
  buf: array[Byte] of Char;
begin
  GetWindowText(hwnd, buf, SizeOf(buf));
  if buf <> '' then Form1.ListBox1.Items.Add(buf);
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  EnumWindows(@EnumWindowsProc_2, 0);
end;

 
 
 
 
 

 

 

  

例三: 查找第一个记事本的句柄

function EnumWindowsProc_3(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
var
  buf: array[Byte] of Char;
begin
  GetClassName(hwnd, buf, SizeOf(buf));
  if buf = 'Notepad' then
  begin
    Form1.ListBox1.Items.Add(Format('记事本句柄: %d', [hwnd]));
    Result := False; //如果不需要继续找, 找到第一个就结束
  end
  else
  begin
    Result := True;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  EnumWindows(@EnumWindowsProc_3, 0);
end;

 
 
 
 
 

 

 

  

例四: 获取所有顶层窗口的句柄与类名数组:

type
  TMyStruct = record
    hwnd: HWND;
    ClassName: string;
  end;
  TMyStructArray = array of TMyStruct;
  PMyStructArray = ^TMyStructArray;

function EnumWindowsProc_4(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
var
  buf: array[Byte] of Char;
  p: PMyStructArray;
begin
  GetClassName(hwnd, buf, SizeOf(buf));
  p := PMyStructArray(lParam);
  SetLength(p^, Length(p^) + 1);
  p^[High(p^)].hwnd := hwnd;
  p^[High(p^)].ClassName := buf;
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Arr: TMyStructArray;
begin
  EnumWindows(@EnumWindowsProc_4, Integer(@Arr));
  ShowMessage(IntToStr(Length(Arr)));                         //总数
  ShowMessageFmt('%d - %s', [Arr[0].hwnd, Arr[0].ClassName]); //第一个元素
end;

 
 
 
 
 

 

 

  

例五: 重复上一个例子, 如果数组是全局遍历并不靠参数传递, 代码会简单些

type
  TMyStruct = record
    hwnd: HWND;
    ClassName: string;
  end;
var
  Arr: array of TMyStruct;

function EnumWindowsProc_5(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
var
  buf: array[Byte] of Char;
begin
  GetClassName(hwnd, buf, SizeOf(buf));
  SetLength(Arr, Length(Arr) + 1);
  Arr[High(Arr)].hwnd := hwnd;
  Arr[High(Arr)].ClassName := buf;
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetLength(Arr, 0);
  EnumWindows(@EnumWindowsProc_5, Integer(Arr));
  ShowMessage(IntToStr(Length(Arr)));                         //总数
  ShowMessageFmt('%d - %s', [Arr[0].hwnd, Arr[0].ClassName]); //第一个元素
end;

 
 
 
 
 

 

 

  

SplendourChiang 的目的是获取进程 ID 和窗口句柄的数组, 按 "例四" 的方法给修改如下:

type
  MyProcessInfo = record
    PID, WinHWND : DWORD;
  end;
  TMyProcessInfoArray = array of MyProcessInfo;
  PMyProcessInfoArray = ^TMyProcessInfoArray;

function MyEnumWindowsProc(Wnd: DWORD; lParam: LPARAM): Bool; stdcall;
var
  PID : DWORD;
  p: PMyProcessInfoArray;
begin
  GetWindowThreadProcessID(Wnd, @PID);
  p := PMyProcessInfoArray(lParam);
  SetLength(p^, Length(p^) + 1);
  p^[High(p^)].PID := PID;
  p^[High(p^)].WinHWND := Wnd;
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  CC: TMyProcessInfoArray;
begin
  SetLength(CC, 0);
  EnumWindows(@MyEnumWindowsProc, Integer(@CC));
  ShowMessage(IntToStr(Length(CC)));                     //总数
  ShowMessageFmt('%d - %d', [CC[0].PID, CC[0].WinHWND]); //第一个元素
end;

 
 
 
 
 

 

 

  

本文转载自:http://www.cnblogs.com/del/archive/2009/12/18/1627110.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
Delphi 查找标题已知的窗口句柄,遍历窗口控件句柄(转)

Delphi 查找标题已知的窗口句柄,遍历窗口控件句柄(转) 用我的方法来控制其他程序窗体上的窗口控件,必须先了解什么是回调函数。我的理解是这样的: 回调函数写出来不是自己的程序去调用的,...

vga
2015/02/05
0
0
Windows窗体数据抓取详解

最近在客户项目上刚好遇到一个问题,项目需求是要获取某台机床的实时状态,问题点刚好就在于该机床不是传统意义上的数控机床,也不是PLC控制器,只有一个上传下载程序文件的应用程序,上面刚...

wangqiulin123456
04/22
0
0
GetSafeHwnd()和GetSafeHandle()区别

一、GetSafeHwnd()和GetSafeHandle()的主要区别: 1、使用者不同 1)窗体使用 GetSafeHwnd()用于获取窗体的安全句柄(即HWND),有了HWND我们就可以方便的对HWND指向的窗体进行所需的操作了 ...

tomy000
2015/01/07
0
0
EnumChildWindows (user32)

C# Signature: [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam)......

一个长老
2012/10/14
0
0
用C#调用Windows API向指定窗口发送按键消息

用C#调用Windows API向指定窗口发送 一、调用Windows API。  C#下调用Windows API方法如下:  1、引入命名空间:using System.Runtime.InteropServices;  2、引用需要使用的方法,格式:[...

RablePHP
2016/06/03
723
0
python3如何获得前端显示窗口的句柄?

我只知道以下代码可以显示所有的可见窗口. 但是我想要前端显示的窗口,应该怎么做? from win32gui import * titles = set() def foo(hwnd,nouse): if IsWindow(hwnd) and IsWindowEnabled(hw...

FakeThinker
2014/07/02
1K
0
详解命令-sesearch

详解命令-sesearch Ronny 2小时前暂无评论 阅读 27 次 使用seinfo命令可以查询SELinux的策略提供多少相关规则,如果查到的相关类型或者布尔值,想要知道详细规则时,使用sesearch命令查询。S...

Ronny
01/08
0
0
揭秘Linux 监控系统 Linux-dash

揭秘Linux 监控系统 Linux-dash Ronny 2小时前暂无评论 阅读 42 次 Linux-dash 详细介绍 Linux-dash 是一个低开销 Linux 服务器监控系统,基于 Web 的监控界面。Linux-dash 的界面提供了一个...

Ronny
01/10
0
0
Visual Studio 11开发指南(17)C++11更新- Lambda表达式

Visual Studio 2010 年以来有可能在 c + + 代码中,和更具体地 STL 使用 Lambda 表达式 (匿名方法的窗体)。例如,看下面的代码执行,当使用这些类型的算法foreach、 parallelfor、 parall...

junwong
2012/03/09
0
0
VC++常用数据类型及其操作详解

一.VC常用数据类型列表 二.常用数据类型转化 2.1数学类型变量与字符串相互转换 2.2 CString及string,char 与其他数据类型的转换和操作 ●CString,string,char的综合比较 ●数学类型与CString...

晨曦之光
2012/03/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

springboot常用注解

@SpringBootApplication: 包含@Configuration、@EnableAutoConfiguration、@ComponentScan 通常用在主类上。 @Service: 用于标注业务层组件。 @RestController: 用于标注控制层组件(如strut...

GoldenVein
6分钟前
0
0
梯度下降法求多元线性回归及Java实现

对于数据分析而言,我们总是极力找数学模型来描述数据发生的规律, 有的数据我们在二维空间就可以描述,有的数据则需要映射到更高维的空间。数据表现出来的分布可能是完全离散的,也可能是聚...

冷血狂魔
11分钟前
2
0
如何进行大数据的入门级学习?

不知道你是计算机专业应届生还是已经从业者。总之,有java基础的学生学习大数据会轻松很多,零基础的小白都需要从java和linux学起。 如果你是一个学习能力特别强,而且自律性也很强的人的话可...

董黎明
20分钟前
0
0
使用Parcelable传递复杂参数

最近做AIDL传递对象,对象必须实现Parcelable的方法才可以被传递。 @Override    public int describeContents() {//这个 默认返回0就行了。        return 0;    }    ...

火云
21分钟前
0
0
十大Intellij IDEA快捷键

Intellij IDEA中有很多快捷键让人爱不释手,stackoverflow上也有一些有趣的讨论。每个人都有自己的最爱,想排出个理想的榜单还真是困难。以前也整理过Intellij的快捷键,这次就按照我日常开发...

HJCui
31分钟前
0
0
word 使用mathtype 编写 数学公式

下载安装,这个链接命名。。。。 http://www.mathtype.cn/xiazai.html 安装之后会多出一个选项 使用内联方式插入图表 编写公式的界面 设置支持latex 语法 输入公式回车就可以看到结果...

阿豪boy
49分钟前
0
0
Promise

定义 Promise是异步编程的一种解决方案,所谓Promise就是一个容器,里面保存着某个未来才会结束的事件(通常是一个一步操作)的结果。 特点: 2.1 对象的状态不受外界影响,三种状态pending...

litCabbage
今天
1
0
设计模式:适配器模式

说明:在不改变旧接口代码的前提下,为该接口新增其他接口的功能 适配器模式可以分为:类适配器模式、对象适配器模式、接口适配器模式 前两种模式下,我会以播放器为例。老版的播放器(Playe...

人觉非常君
今天
0
0
使用VsCode搭建Java开发环境,创建springboot应用

1、在 Visual Studio Code 中打开扩展视图(Ctrl+Shift+X),输入关键词java、spring分别下载Java开发插件包和springboot插件包 2、配置参数 点击设置按钮,进入设置选项,配置用户设置 在用户...

qsyan
今天
23
0
调教属于你的“贾维斯”(给自己挖了一个很大的坑)

今天玩一下现在很火的人工智能。 废话不多说,先来看几张图: 看出什么蹊跷了吗? 再来看一个视频: https://www.zhihu.com/video/1002567561061511168 (演示网址和代码见文末) 人工智能离...

crossin
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部