我用Hook监视一个目标窗口的出现,并在窗口出现后,获取到几个相关的窗体句柄
其中一个产品名称列表下拉框,一个产品编号文本框
在程序中直接操作的时候,应该是先选择下拉框中产品,此时会触发下拉框的Onclick事件,进行一些数据读取的处理,然后输入产品编号,在输入产品编号的过程中,每输入一个数字,都会触发一个事件,对产品名称和编号进行比较,如果比较通过,则该窗口直接进入下一个填写界面。我现在通过WM_WINDOWPOSCHANGING消息Hook监视该目标窗口,并且模拟下拉框选择和产品编号的填写,但是总是导致目标程序出错,一直找不到原因。我单独模拟输入产品名称下拉框,程序不出错,
单独模拟输入产品标号,程序也不出错。
但是只要两者一起输入,目标程序就出错了。模拟输入下拉框代码:
var listOrder:Integer;
listOrder:= findComboItemIndex(nameHwnd, productName);//找到要输入的产品名称在下拉列表中的顺序
SendMessage(nameHwnd, CB_SETCURSEL, listOrder, 0);
模拟输入产品编号代码:
SendMessage(codeHwnd, WM_SETTEXT, 0, LongInt(Pchar(productCode)));麻烦大家帮忙分析一下原因,谢谢。
不懂的,不能回答的,就别顶了,我会自己关注帖子,自己提前的,谢谢合作
其中一个产品名称列表下拉框,一个产品编号文本框
在程序中直接操作的时候,应该是先选择下拉框中产品,此时会触发下拉框的Onclick事件,进行一些数据读取的处理,然后输入产品编号,在输入产品编号的过程中,每输入一个数字,都会触发一个事件,对产品名称和编号进行比较,如果比较通过,则该窗口直接进入下一个填写界面。我现在通过WM_WINDOWPOSCHANGING消息Hook监视该目标窗口,并且模拟下拉框选择和产品编号的填写,但是总是导致目标程序出错,一直找不到原因。我单独模拟输入产品名称下拉框,程序不出错,
单独模拟输入产品标号,程序也不出错。
但是只要两者一起输入,目标程序就出错了。模拟输入下拉框代码:
var listOrder:Integer;
listOrder:= findComboItemIndex(nameHwnd, productName);//找到要输入的产品名称在下拉列表中的顺序
SendMessage(nameHwnd, CB_SETCURSEL, listOrder, 0);
模拟输入产品编号代码:
SendMessage(codeHwnd, WM_SETTEXT, 0, LongInt(Pchar(productCode)));麻烦大家帮忙分析一下原因,谢谢。
不懂的,不能回答的,就别顶了,我会自己关注帖子,自己提前的,谢谢合作
解决方案 »
- 如何把DateTimePicker中设置成显示的小时是24小时显示时间
- 求制作自己的IE工具条
- 有关update更新数据库问题 BDE
- 我的dblistbox加了数据 怎么无法点选?
- 24位BMP图转16位
- 追加文本信息------急,在线等。
- 二个问题困了我一天了!用过 RX LIB 275 TDBDateEdit 的朋友帮帮忙好吗?高分等待!倾尽所有都可以!
- getcomputername函数的用法?
- 怎样做winamp那样的声音波形图??
- 二进制字符串和浮点数互相转换
- 如何在delphi中datasource赋值为空
- dll封装多个子窗体时,其中uses了父窗体和datamodule从而无法编译成dll文件,该怎么办呢?
其实就是在你上次帮我改的那个Hook代码里,继续写的。
因为窗口消息处理事件进入我的Dll里了,我的Dll如果Sleep的话,那个程序也停了,我的Sleep结束,那个程序才继续运行。就跟没Sleep一样
就能识别EXE运行出来的
begin
Result := CallNextHookEx(0, nCode, WParam, LParam);
exit;
end; winStruct := PCWPSTRUCT(LParam)^; if winStruct.message <> WM_WINDOWPOSCHANGING then
begin
Result := CallNextHookEx(0, nCode, WParam, LParam);
exit;
end
else
begin
winPos := PWindowPos(winStruct.lParam)^;
if (winPos.flags and SWP_SHOWWINDOW) = 0 then
begin
Result := CallNextHookEx(0, nCode, wParam, lParam);
exit;
end;
if (winPos.hwnd = 0) or (not IsWindow(winPos.hwnd)) then
begin
Result := CallNextHookEx(0, nCode, wParam, lParam);
exit;
end;
end;
//开始模拟录入
上面代码是Hook函数里监视目标窗口的代码,原来意图是那个窗口还没等显示出来,就让其隐藏并且任务栏上看不到相应图标。
我现在隐藏部分都先注释掉了,就没贴上来。
但执行模拟录入的时候,目标窗口还是没显示出来呢,所以就像我上面说的那样,导致错误了。
我是不是应该等目标窗口已经显示出来,再模拟输入啊?
但如果又想隐藏窗口,又不希望程序图标在任务栏显示,又想保证目标窗体完全加载完毕,应该怎么办呢?
我以前发过帖子,直接用一个可执行程序隐藏目标窗口并且不显示任务栏是可行的。
但相同的代码放在Dll里,就达不到效果了。
那这个时候,我应该Hook哪个消息?
谢谢
我先试试去
发送此消息给那个窗口的大小和位置已经被改变时,来调用setwindowpos函数或其它窗口管理函数
发送此消息给那个窗口的大小和位置将要被改变时,来调用setwindowpos函数或其它窗口管理函数
正常来说VB窗体加载的时候,会触发一个Form_Activate事件,并且是在窗体显示出来之前执行的,
但我发现我Hook了WM_WINDOWPOSCHANGED消息的时候,那个窗口的Form_Activate竟然执行了两次。
当我用程序模拟选择了产品名称和编号后,那个VB程序自动将产品名称下拉框和编号文本框隐藏了。
而第二次执行Form_Activate的时候,因为那个窗体上有的文本框已经隐藏了,那在Form_Activate中再次对那个文本框.focus的时候,就出错了。
创建窗体 ...
1. WM_GETMINMAXINFO
2. WM_NCCREATE
3. WM_NCCALCSIZE
4. WM_CREATE
创建完毕.显示窗体 ...
1. WM_SHOWWINDOW
2. WM_WINDOWPOSCHANGING
3. WM_WINDOWPOSCHANGING
4. WM_ACTIVATEAPP
5. WM_NCACTIVATE
6. WM_GETTEXT
7. WM_ACTIVATE
8. WM_SETFOCUS
9. WM_NCPAINT
10. WM_GETTEXT
11. WM_ERASEBKGND
12. WM_WINDOWPOSCHANGED
13. WM_SIZE
14. WM_MOVE
显示完毕.
其他的先不列出来了。
Hook WM_WINDOWPOSCHANGED消息的情况下,其实我之前选择输入产品名称和产品编号的目的确定达到了,比我之前Hook WM_WINDOWPOSCHANGING消息前进了一步。
但是是不理解那个Form_Activate 应该是在我的代码执行之前执行的,怎么之后又执行了一次,并导致错误。
实在想不出来,怎么能绕过去我又不能改动那个VB程序。不允许改。
Hook WM_WINDOWPOSCHANGED 消息和Hook WM_ACTIVATE消息都是这样。
为什么呢?
到底应该Hook哪个消息,保证窗体显示完毕,才执行我的代码呢?
但我现在想不到办法判断窗口显示完毕。
procedure MySleep(Sec: Integer);
var
i: Integer;
begin
i:=0;
while i<100*Sec do
begin
i:=i+1;
Application.ProcessMessages;
Sleep(10);
end;
end;
而直接Sleep会导致目标程序也暂停。