子类化初始工作代码FHookWndProc := MakeObjectInstance(HookWndProc);
OldWndProc := Pointer(GetWindowLong(ParentWindow, GWL_WNDPROC));
SetWindowLong(ParentWindow, GWL_WNDPROC, Longint(FHookWndProc));
OldWndProc的变量类型是Pointer我想把OldWndProc转换类型为String保存成文本文件,用下面的代码可以转换成文本,貌似是函数的地址。ShowMessage(Format('%p', [OldWndProc]));
我的问题是如何把它再转换成Pointer类型并且可以在窗口函数中使用with Msg do
begin
Result := CallWindowProc(OldWndProc, ParentWindow, Msg, WParam, LParam);
end;CallWindowProc函数里面的OldWndProc是通过String类型转换成Pointer类型。谢谢大家,祝春节快乐。
OldWndProc := Pointer(GetWindowLong(ParentWindow, GWL_WNDPROC));
SetWindowLong(ParentWindow, GWL_WNDPROC, Longint(FHookWndProc));
OldWndProc的变量类型是Pointer我想把OldWndProc转换类型为String保存成文本文件,用下面的代码可以转换成文本,貌似是函数的地址。ShowMessage(Format('%p', [OldWndProc]));
我的问题是如何把它再转换成Pointer类型并且可以在窗口函数中使用with Msg do
begin
Result := CallWindowProc(OldWndProc, ParentWindow, Msg, WParam, LParam);
end;CallWindowProc函数里面的OldWndProc是通过String类型转换成Pointer类型。谢谢大家,祝春节快乐。
ParentWindow是IE窗口的句柄。
http://wenku.baidu.com/view/8cd214717fd5360cba1adb71.html
这句是替换原始函数指针gwl_wndproc为你自己的函数newwndproc
oldwndproc=point(setwindowlong(application.handle,gwl_wndproc,intger(newwndproc)));
这句就是还原函数指针gwl_wndproc
setwindowlong(application.handle,gwl_wndproc,intger(oldwndproc));
谢谢高手回复,ie窗口是可以关闭的,只是会报错。这个原因这是清楚的。
具体流程我给你说一下:
1)首先ocx第一次运行取得的ie消息函数地址是正确的,直接关闭ie是没有问题的。复原的地址也是ie的
2)如果再打开一个新的ie标签,再载入相同的ocx这时候取的消息函数就不是ie的了,而是第一次ocx的消息处理函数,这样就会有一个问题,如果关闭第一个ocx网页,再关闭第二个的话,ie报错。这是因为关闭第一个网页的时候消息函数地址也被ie收回了,第二个网页复原的时候地址不存在。错非先关闭第二个ocx,再关闭第一个是正常的。
ie是多标签浏览器,每个标签类名是frame tab,所以的标签都是ie的子窗体。我是把这个地址值保存到一个文件中,如果需要多次加载ocx我就读取这个文件把ie的函数地址复原,以后关闭整个ie窗口的时候,可以复原所有正确的ie窗口地址。比如说我有10个标签页都载入这个ocx,直接关闭ie肯定出错。我不太清楚关闭整个ie标签页回收资源的顺序。但可以肯定的是,这10个页面我按照后进先出的顺序,一个个关闭程序是完成正常的。如果先把第一个ocx关了,那么关闭其它任意9个页面当中的一个都会直接报错。
现在我又加载一次ocx,下面的代码OldWndProc保存的地址其实是第一次加载ocx的消息处理函数地址
FHookWndProc := MakeObjectInstance(HookWndProc);
OldWndProc := Pointer(GetWindowLong(ParentWindow, GWL_WNDPROC));
SetWindowLong(ParentWindow, GWL_WNDPROC, Longint(FHookWndProc));
如果把第一次加载的ocx网页关闭了
那么第二次加载的ocx在恢复窗口地址的时候就会出错,原因他要恢复的地址已经被ie回收了
SetWindowLong(ParentWindow, GWL_WNDPROC, Longint(OldWndProc));
这里的OleWndProc地址其实是第一个ocx的消息处理函数。
DLL_PROCESS_ATTACH:
DLL_PROCESS_DETACH:
DLL_THREAD_ATTACH:
DLL_THREAD_DETACH:
高手别啊,其实只要在第一次运行ocx的时候把OleWndProc保存住,以后再子类化的时候就用保存的函数地址就行。我现在卡在这里了,不知道如何把这个oldwndproc持久化。
我貌似搞定了,我用txt文件保存ie原始窗口函数,只有第一次创建文本文件,以后的加载直接读文本文件,把里面的地址转换就行了,就是有一点不好,还要维护这个文本文件。 fn := 'c:\' + IntToStr(ParentWindow) + '.txt';
AssignFile(F, fn);
if (FileExists(fn)) then
begin
Reset(F);
Readln(F, cc);
ShowMessage(cc);
OldWndProc := Pointer(StrToInt('$'+ cc));
end else
begin
OldWndProc := Pointer(GetWindowLong(ParentWindow, GWL_WNDPROC));
Rewrite(F);
Writeln(F, Format('%p', [OldWndProc]));
end;
CloseFile(F);