最近由于要写一套集中登录的系统,着重研究了一下Windows的窗口编程的问题,对得出的结论和经验,跟大家共享一下。
绝大多数的程序开发者是通过spy++等工具,发现第三方工具的classname或caption,通过FindWindow函数来获取窗口句柄的,但是这样也存在问题,如果第三方开发商修改了启动的窗口类名,怎么办?所以就衍生了下面这个方法。
我们在制作集中登录系统的时候,对于BS结构的系统,大多都是通过Post登录链接实现的,CS的系统,就只好通过捕捉登录画面,通过windows的消息,实现对特定窗口控件的自动填充实现的,这就涉及倒如何识别窗口中各个控件的句柄,一般,如果窗体中用户ID的输入框和密码输入框不是同一种控件,都是很好解决的,但如果都是Eidt这种类型的控件,该如何解决?,下面我就详细给大家解析。
我们主要目的是不使用Spy++的帮助,这要求我们要利用CreateProcess,这个函数,启动我们需要的窗口,参数如下
var
SI : TStartupInfo;
PI : TProcessInformation;
CreateProcess(nil,'CALC.EXE', nil, nil, FALSE, 0 ,nil,nil, SI, PI
这样,我们就可以获取我们需要监控的程序的主句柄
var
SI : TStartupInfo;
PI : TProcessInformation;
H : THandle;
S : String;
begin
ZeroMemory(@SI, SizeOf(SI));
ZeroMemory(@PI, SizeOf(PI));
SI.cb : = SizeOf(SI);
if CreateProcess(nil, ' CALC.EXE ' , nil, nil, FALSE, 0 ,nil,nil, SI, PI) then
begin
// 注意!
WaitForInputIdle(PI.hProcess, INFINITE);
H : = FindMainWindow(PI.dwProcessID);
if H > 0 then
begin
SetLength(S, 255 );
GetWindowText(H, PChar(S), 255 );
SetLength(S, StrLen(PChar(S)));
ShowMessage(S);
end;
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
SI : TStartupInfo;
PI : TProcessInformation;
H : THandle;
S : String;
begin
ZeroMemory(@SI, SizeOf(SI));
ZeroMemory(@PI, SizeOf(PI));
SI.cb : = SizeOf(SI);
if CreateProcess(nil, ' CALC.EXE ' , nil, nil, FALSE, 0 ,nil,nil, SI, PI) then
begin
// 注意!
WaitForInputIdle(PI.hProcess, INFINITE);
H : = FindMainWindow(PI.dwProcessID);
if H > 0 then
begin
SetLength(S, 255 );
GetWindowText(H, PChar(S), 255 );
SetLength(S, StrLen(PChar(S)));
ShowMessage(S);
end;
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
这样,实际上就可以监控那个我们需要的窗口句柄了,
下面处理窗体上重复的控件句柄。
(待续。。。 绝对变成最强的window监控最强帖)