回调函数一般是按照调用者的要求定义好参数和返回值的类型,你向调用者提供你的回调函数的入口地址,然后调用者有什么事件发生的时候就可以随时按照你提供的地址调用这个函数通知你,并按照预先规定好的形式传递参数。所以很多人打比方,说回调函数还真有点像您随身带的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. yum与rpm的使用

    rpm常用的命令组合: rpm -ivh:安装显示安装进度--install--verbose--hash -Uvh:升级软件包--Update: -qpl:列出RPM软件包内的文件信息[Query ...

  2. /dev/tty /dev/ttyS0 /dev/tty0区别 (转载)

    1.串行端口终端(/dev/ttySn)     串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备.    计算机把每个串行端口都看作是一个字符设备.有段时间 ...

  3. MATLAB学习笔记(八)——MATLAB数值积分与微分

    (一)数值积分 一.数值积分的MATLAB实现方法: 1.变步长辛普生法(quad)法: (1)调用格式: [I,n]=quad('fname',a,b,tol,trace); fname是被积函数: ...

  4. C#环境datagidview添加删除操作

    添加 行 dataGridView1.Rows.Add();//添加空行 dataGridView1.Rows.Add("a","b"……);//添加指定列数的 ...

  5. Win7-64bit系统下安装mysql的ODBC驱动

    安装过mysql数据库后,有些软件在调用mysql数据库时不会直接调用,需要安装mysql数据库的ODBC驱动,再来调用.这里就介绍下,如何在win7系统下安装mysql的ODBC驱动. Win7系统 ...

  6. Beaglebone Black的启动

    Beaglebone Black的启动 第1章  准备开始 Beaglebone Black上最显眼的恐怕就是板子两侧的扩展端口,一侧有46个端口,共92个端口Beaglebone Black的启动. ...

  7. Redis String命令

        命令 解释 APPEND key value 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾. 如果 key 不存在, APPEND ...

  8. Codeforces 219D Choosing Capital for Treeland(树形DP)

    题目是给一张边有向的树形图.要选出首都的点,首都要都能走到其他点,因此要反转一些边的方向.问可以选哪几个点作为首都,使它们所需反转边的数量最少. 这题挺好想的,因为做过HDU2196. 首先就不妨设正 ...

  9. BZOJ3103 : Palindromic Equivalence

    用Manacher可以推出O(n)对相等和不等关系. 将相等的用并查集维护,不等的连边. 然后从1到n,如果该等价类还没被考虑过,则ans*=26-与它不等的考虑过的等价类个数. #include&l ...

  10. storm Tutorial 的解读 + 个人理解

    参考链接: Tutorial storm Tutorial 中文解读+分析 导读.摘要: .hadoop有master与slave,Storm与之对应的节点是什么? .Storm控制节点上面运行一个后 ...