回调函数一般是按照调用者的要求定义好参数和返回值的类型,你向调用者提供你的回调函数的入口地址,然后调用者有什么事件发生的时候就可以随时按照你提供的地址调用这个函数通知你,并按照预先规定好的形式传递参数。所以很多人打比方,说回调函数还真有点像您随身带的BP机:告诉别人号码,在它有事情时Call您!

所以一个回调函数写出来之后,一定有个注册的动作,就是告诉调用者,你怎么样找到我写的函数。某些Windows API 函数会要求以回调函数地址作为其参数之一,例如SetTimer 、LineDDA 、EnumObjects,以及我们下面要用到的EnumWindows。

在Delphi里声明一个回调函数的格式很简单,例如:

function EnumWindowsProc(AhWnd:LongInt;lParam:LongInt):boolean;stdcall;

首先是函数名称可以随便乱取,但函数参数的类型一般不得乱来,其顺序,数据类型等都有规定的,因为这些都是让其他程序调用的,他们已经规定好了的,但参数名称可以随便乱叫。注意后面一定要带上“stdcall”,

stdcall是标准调用,也就是说采用标准windows参数传递方式来调用函数。

编写函数体就很简单了,利用传递过来的参数就可以了,只要记住,这些参数是别人送给你的,你只要知道这些参数代表了什么意思。

再看个向调用者注册回调函数入口地址的函数。  function EnumWindows(lpEnumFunc: TFNWndEnumProc; lParam: LPARAM): BOOL; stdcall;

TFNWndEnumProc其实就是指针类型。其中的lpEnumFunc就是回调函数的入口地址了。

下面是调用EnumWindows的格式: EnumWindows(@EnumWindowsProc,0);

通过向系统注册回调函数的入口地址,系统就能在需要的时候,调用回调函数,传递参数给它,也许这些参数就是我们想要的。

EnumWindows函数的功能是:枚举屏幕上所有程序中的顶层窗口,将窗口句柄以参数的形式传递给回调函数。找到一个窗口,就调用一次回调函数。枚举结束的条件是:要么枚举完所有的窗口,要么回调函数返回False。

lParam: LPARAM参数是程序定义的值,这个值被传递到回调函数。

回过头来再看一下EnumWindowsProc:

function EnumWindowsProc(AhWnd:LongInt;lParam:LongInt):boolean;stdcall;

当系统找到了一个窗口后,就开始调用这个回调函数,将窗口的句柄作为第一个参数传递过来,将在EnumWindows中lParam: LPARAM这个程序定义的值作为第二个参数传递过来。

所以我们可以在EnumWindowsProc函数中利用传递过来的两个参数来做某些处理了。

下面我们新建一个程序列举系统中所有程序的顶层窗口,我们要得到窗口的标题,要得到窗口类名称。

得到窗口标题用:

function GetWindowText(hWnd: HWND; lpString: PChar; nMaxCount: Integer): Integer; stdcall;

该函数功能是将窗口句柄为hWnd的窗口的标题拷入到一个缓冲区lpString。nMaxCount是拷入缓冲区内的最大的字符数。

要得到窗口标题还可以发送消息:WM_GETTEXT,其实GetWindowText就是发送WM_GETTEXT消息的。

要得到窗口类名称用:

function GetClassName(hWnd: HWND; lpClassName: PChar; nMaxCount: Integer): Integer; stdcall;

其参数意义和上面的函数差不多。不详细解释了。

我们先编写回调函数:EnumWindowsProc。现在告诉自己,我们已经有了两个参数的值了。这两个参数是系统给我们的.

为了显示窗口标题和类名,我们用一个TMemo控件。

先在interface部分声明函数。

function EnumWindowsProc(AhWnd:LongInt;AForm:TForm1):boolean;stdcall;

注意我将第二个参数改了,不要紧,到时候调用的时候注意看。

然后在implementation部分定义函数:

function EnumWindowsProc(AhWnd:LongInt;AForm:TForm1):boolean; 

var 
lpszClassName,lpszWindowText:array[..] of char; //定义两个缓冲区。
begin
GetWindowText(AhWnd,lpszWindowText,); //得到窗口标题
GetClassName(AhWnd,lpszClassName,); //得到窗口类名。
Aform.memo1.lines.add(StrPas(lpszWindowText));
Aform.memo1.lines.add(StrPas(lpszClassName));
Aform.memo1.lines.add(’--------------------’);
Result:=True;
end;

接着需要做的就是调用EnumWindows函数,注册回调函数入口地址,让系统调用回调函数,列举窗口了。所以再添加一个TButton: btn_listwindow

procedure TForm1.btn_listwindowClick(Sender: TObject); 
begin
EnumWindows(@EnumWindowsProc,LongInt(self));
end; unit Unit1; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type
TForm1 = class(TForm)
Memo1: TMemo;
btn_listwindow: TButton;
procedure btn_listwindowClick(Sender: TObject);
private { Private declarations }
public { Public declarations }
end; var Form1: TForm1; function EnumWindowsProc(AhWnd:LongInt;AForm:TForm1):boolean;stdcall; implementation {$R *.dfm}
function EnumWindowsProc(AhWnd:LongInt;AForm:TForm1):boolean;
var lpszClassName,lpszWindowText:array[..] of char;
begin
GetWindowText(AhWnd,lpszWindowText,);
GetClassName(AhWnd,lpszClassName,);
Aform.memo1.lines.add(StrPas(lpszWindowText));
Aform.memo1.lines.add(StrPas(lpszClassName));
Aform.memo1.lines.add(’--------------------’);
Result:=True;
end; procedure TForm1.btn_listwindowClick(Sender: TObject);
begin
EnumWindows(@EnumWindowsProc,LongInt(self));
end;

end.

F9,运行,看看结果。最好是F7单步跟踪调试一下,看看回调函数是怎么被调用的 本文来自Delphi之窗,原文地址:http://www.52delphi.com

Delphi中如何控制其他程序窗体上的窗口控件的更多相关文章

  1. Delphi 查找标题已知的窗口句柄,遍历窗口控件句柄(转)

    用我的方法来控制其他程序窗体上的窗口控件,必须先了解什么是 回调函数.我的理解是这样的: 回 调函数写出来不是自己的程序去调用的,反而是让其他的东西去调用,比如windows操作系统,比如其他的程序等 ...

  2. Delphi 查找标题已知的窗口句柄,遍历窗口控件句柄

    有了回调函数的概念及上面的例子,我们可以继续了.其实想要找到一个标题已知的窗口句柄,用一个API函数就可以了:FindWindow.其函数原形是:function FindWindow(lpClass ...

  3. delphi7 如何描述窗体上的全部控件

    在delphi开发中,经常需要用到窗体中控件的name名来进行对象方法或属性的调用,所以如何对delphi窗体进行简洁,清楚,完整的描述就很重要.最好能不看界面也能进行界面编码,具体如下表所示: xx ...

  4. 在wpf窗体上添加用户控件

    1.引用用户控件的命名控件 xmlns:my="clr-namespace:WpfApplicationDemo.Control" 2.把用户控件添加到窗体中 <my:Use ...

  5. C# 在窗体上可拖动控件

    最近做了一个标签打印配置功能,需要根据客户需求自定义标签格式.显示内容,这时就用到了后台生成控件,并且其控件可在窗口中进行拖动,这里仅为记录一下实现过程,方便以后使用. 结果图: 源码: using ...

  6. 当一个窗体上有PageControl 控件时,是先执行 FormShow呢,还是先执行PageControl 的 TabSheet2Show呢

    答案是 先执行 TabSheet2Show  ,总算知道了,顺便推理 Onshow事件的执行顺序是 从内到外,先执行容器内的控件的事件,再执行 窗体的事件

  7. WM_ERASEBKGND官方解释(翻译),以及Delphi里所有的使用情况(就是绘制窗口控件背景色,并阻止进一步传递消息)

    #define WM_ERASEBKGND                   0x0014 Parameters wParam A handle to the device context. //  ...

  8. WPF Prism MVVM 中 弹出新窗体. 放入用户控件

    原文:WPF Prism MVVM 中 弹出新窗体. 放入用户控件 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_37214567/artic ...

  9. 《zw版·delphi与halcon系列原创教程》zw版_THOperatorSetX控件函数列表 v11中文增强版

    <zw版·delphi与halcon系列原创教程>zw版_THOperatorSetX控件函数列表v11中文增强版 Halcon虽然庞大,光HALCONXLib_TLB.pas文件,源码就 ...

随机推荐

  1. 错误解决error while loading shared libraries: libXXX.so.X: cannot open shared object file: No such file

    转自:http://blog.csdn.net/david_xtd/article/details/7625626 前提:ubuntu-debug机器上向SVN提交了pdu-IVT,想在别的普通机器上 ...

  2. loj 1221(spfa判正环)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25957 思路:由于路线为一个环,将路径上的权值改为c-p*d,那么 ...

  3. HUE的时区问题

    转自 http://molisa.iteye.com/blog/1953390   我主要是根据这个说明调整的HUE的时区问题 在使用Cloudera Hue时遇到一问题: 1. 使用Sqoop导入功 ...

  4. 10686 DeathGod不知道的事情

    Description 蚂蚁是很强大的动物,除了DeathGod知道的事情外还有很多不知道的!例如… 根据某种理论,时间方向上有无数个平行世界,有的世界蚂蚁很多,有的世界蚂蚁很少,有的世界蚂蚁会繁殖, ...

  5. Ubuntu 安装Redis体验

      背景:由于之前一直没有试过Linux的环境,今天加了内存之后,虚拟机开了3G,速度大大提高,对照博客试一下安装Redis的过程.   体验: 下载源码,解压,编译 $ wget http://do ...

  6. Piggy-Bank[HDU1114]

    Piggy-Bank Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  7. 追本溯源 解析“大数据生态环境”发展现状(CSDN)

    程学旗先生是中科院计算所副总工.研究员.博士生导师.网络科学与技术重点实验室主任.本次程学旗带来了中国大数据生态系统的基础问题方面的内容分享.大数据的发展越来越快,但是对于大数据的认知大都还停留在最初 ...

  8. 【转】Eclipse Plugin 在 Console上打印出message

    org.eclipse.ui.console 转自:http://blog.csdn.net/rujielaisusan/article/details/4505188 首先这里主要用到的是org.e ...

  9. 20145325张梓靖 实验五 "JAVA的网络编程"

    20145325张梓靖 实验五 "JAVA的网络编程" 实验内容 使用 JVAV语言 进行网络编程 对明文进行加密 设计过程 我完成的是客户端,服务端同伴 20145308刘昊阳 ...

  10. jpeglib使用指南

    您可以到http://www.ijg.org/网站下载libjpeg的源码, IJG JPEG Library就是jpeg压缩库,是以源码的形式提供给软件开发人员的,当然在软件包里也有编译好的库文件, ...