毛孔有白色的颗粒是啥:为什么我用delphi编程获取窗口句柄不成功?

来源:百度文库 编辑:神马品牌网 时间:2024/04/28 21:36:40
非常简单的一段代码,或是却不能正确获取窗口句柄,想请教高手。
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm1 = class(TForm)

private
{ Private declarations }

public
{ Public declarations }
end;

var
Form1: TForm1;
hw:HWND;
Pid:Dword;
h:Thandle;
tt:Cardinal;
ss:string;

implementation

{$R *.nfm}
begin
hw:=Findwindow('QQ.exe',nil);
if hw = 0 then showmessage('未发现QQ')
else
showmessage('发现QQ');
GetWindowThreadProcessId(hw,Pid);
h := OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if h=0 then exit;
closehandle(h);

end.

end.

这个函数hw:=Findwindow('QQ.exe',nil)我改成hw:=Findwindow('QQ',nil)等,换成其他的窗口也不能成功,请问如何才能正确获取窗口名柄啊!
非常谢谢,但是如果不是想获取QQ句柄,而是想获取其他程序句柄,该如何处理?另外spy++哪有下载的?

我是用VC的,delphi不是很懂,不过API还是一样的,说说我的意见。

Findwindow()的第一个参数是表示类名的字符串,第二个参数是表示窗口标题的字符串,你的第一个参数设置错了,QQ主窗口的类是对话框,应该用"#32770"表示,你可以用Spy++查看的。第二个参数也不对,如果设置成nil,那么任意标题的"#32770"类的窗口都会匹配,而它返回的只是找到的第一个窗口的句柄,不一定是QQ。QQ主窗口的标题是空字符串。

但实际上,你即使用FindWindow("#32770","")找到了相应的句柄,它也不一定是QQ的。因为参数里没有任何QQ特有的信息,而系统中存在大量"#32770"的对话框,它们的标题也各种各样,很可能就有空字符串,而它返回的是找到的第一个窗口的句柄,不能保证一定是QQ。所以这个办法很差。较为可行的方法是枚举系统当前的所有进程,从中查找模块名为"QQ"的进程,从进程中查找属于该进程的窗口,当然也不排除存在其他的名为QQ的进程,但这个可能性应该比较小。

我曾经做过针对QQ的一个插件,这是做的过程中的一些体会。

例子:
function FindQQWindow: THandle;

function GetSpecialButtonHandle(hwnd: HWND; lParam: LPARAM):Boolean; stdcall;
var
cName: array[0..128] of Char;
wName: array[0..128] of Char;
begin
result := true;
GetClassName(hwnd, cName, 128);
if StrPas(cName) = 'Button' then
begin
GetWindowText(hwnd, wName, 128);
if StrPas(wName) = '软键盘'then
begin
FQQVersion := 'V2004Beta';
PInteger(lParam)^ := hwnd;
result := false;
end;
if StrPas(wName) = '注册向导' then
begin
FQQVersion := 'V2003';
PInteger(lParam)^ := hwnd;
result := false;
end;
end;
end;

function EnumWindowsProc(hwnd: HWND; lParam: LPARAM): boolean; stdcall;
var
eName: array[0..180] of Char;
begin
Result := true;
if hwnd = 0 then Exit;
GetClassName(hwnd, eName, 32);

If CompareText('#32770', StrPas(eName))<>0 Then Exit;

EnumChildWindows(hwnd, @GetSpecialButtonHandle, Integer(@HSpecialHandle));
if HSpecialHandle <> 0 then
Begin
QQHandle:= hwnd;
Result := False;
End;
end;
begin
QQHandle:= 0;
EnumWindows(@EnumWindowsProc, 0);
Result:= QQHandle;
end;

{-------------------------------------------------------------------------------
说明: 取得QQ窗口的各个编辑框以及登陆按钮的句柄
-------------------------------------------------------------------------------}
procedure GetQQHandle;
Var
eHandle: THandle;
begin
eHandle:= FindQQWindow;
if eHandle<>0 then
begin
HPasswordEdit:= FindWindowEx(eHandle, 0, 'Edit', nil);
HNumberEdit:= FindWindowEx(eHandle, 0, 'Combobox', nil);
HLoginButton:= FindWindowEx(eHandle, 0, 'Button', '登录');
end;
end;

{-------------------------------------------------------------------------------
说明: 启动QQ后,计时器开始检测QQ窗口的存在,
检测到了,发送用户名密码到指定编辑框再模拟点击QQ登陆按钮完成登陆
-------------------------------------------------------------------------------}
procedure TQQLogin.FTimerTimer(Sender: TObject);
var
i: integer;
begin
GetQQHandle;

If (HNumberEdit=0) or (HPasswordEdit=0) or (HLoginButton=0) Then Exit;

SendMessage(HNumberEdit, WM_SETTEXT, 0, Integer(FUserId));

if FQQVersion = 'V2004Beta' then
begin
For I:= 1 To Length(FPassword) Do
SendMessage(HPasswordEdit, WM_USER+513, Integer(FPassword[I]), 0);
end
else
begin
For I:= 1 To Length(FPassword) Do
begin
SendMessage(HPasswordEdit, WM_CHAR, Integer(FPassword[I]), 0);
end;
end;

SendMessage(HLoginButton, WM_LBUTTONDOWN, 0, 0);
SendMessage(HLoginButton, WM_LBUTTONUP, 0, 0);

FTimer.Enabled := False;
Free;
end;