扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
EXE file: LRESUlT WndProc(HWND hend,UNIT uMsg,...){.....} USER32.DLL file LONG DispatchMessage(CONST MSG*msg) { LONG lRet; WNDPROC lpfnWndProc= (WNDPROC)GetWindowLongPtr(msg,hwnd,GWLP_WNDPROC ); lRet=lpfnWndProc(msg.hwnd,msg.message,msg.wParam,mag. lParam); return lRet; } 进程B中: EXE file void Somefunc(void) { HWND hwnd=Findwindow("class A",NULL); SetWindowLongPtr(hwnd,GWLP_WNDPROC,MySubclassProc); } USER32.DLL file ...... |
换句话说,当系统需要将消息发送到指定窗口的WndProc时,要查看它的地址,然后直接调用WndProc。在本例中,系统发现MySubclassProc函数的地址与窗口相关联,因此就直接调用MySubclassProc函数。
为另一个进程创建的窗口建立子类时遇到的问题是,建立子类的过程位于另一个地址空间中。下面举个例子,说明窗口过程是如何接受消息的。进程A正在运行,并且已经创建了一个窗口。文件User32.dll被映射到进程A的地址空间中。
对User32.dll文件的映射是为了接收和发送在进程A中运行的任何线程创建的任何窗口中发送和显示的消息。当User32.dll的映像发现一个消息时,它首先要确定窗口的WndProc的地址,然后调用该地址,传递窗口的句柄、消息和wParam和lParam值。当WndProc处理该消息后,User32.dll便循环运行,并等待另一个窗口消息被处理。
进程B中的线程试图为进程A中的线程创建的窗口建立子类现在假设你的进程是进程B,你想为进程A中的线程创建的窗口建立子类。你在进程B中的代码必须首先确定你想要建立子类的窗口的句柄。这个操作使用的方法很多。上面的例子只是调用FindWindow函数来获得需要的窗口。接着,进程B中的线程调用SetWindowLongPtr函数,试图改变窗口的WndProc的地址。请注意我说的“试图”二字。这个函数调用⒉进行什么操作,它只是返回NULL。SetWindowLongPtr函数中的代码要查看是否有一个进程正在试图改变另一个进程创建的窗口的WndProc地址,然后将忽略这个函数的调用。
如果SetWindowLongPtr函数能够改变窗口的WndProc,那将出现什么情况呢?系统将把MySubclassProc的地址与特定的窗口关联起来。然后,当有一条消息被发送到这个窗口中时,进程A中的User32代码将检索该消息,获得MySubclassProc的地址,并试图调用这个地址。但是,这时可能遇到一个大问题。MySubclassProc将位于进程B的地址空间中,而进程A是个活动进程。显然,如果User32想要调用该地址,它就要调用进程A的地址空间中的一个地址,这就可能造成内存访问的违规。
为了避免这个问题的产生,应该让系统知道M y S u b c l a s s P r o c是在进程B的地址空间中,然后,在调用子类的过程之前,让系统执行一次上下文转换。M i c r o s o f t没有实现这个辅助函数功能,原因是:应用程序很少需要为其他进程的线程创建的窗口建立子类。大多数应用程序只是为它们自己创建的窗口建立子类,Wi n d o w s的内存结构并不阻止这种创建操作。
切换活动进程需要占用许多C P U时间。
进程B中的线程必须执行M y S u b c l a s s P r o c中的代码。系统究竟应该使用哪个线程呢?是现有的线程,还是新线程呢?
U s e r 3 2 . d l l怎样才能说明与窗口相关的地址是用于另一个进程中的过程,还是用于同一个进程中的过程呢?
由于对这个问题的解决并没有什么万全之策,因此M i c r o s o f t决定不让S e t Wi n d o w s L o n g P t r改变另一个进程创建的窗口过程。不过仍然可以为另一个进程创建的窗口建立子类—只需要用另一种方法来进行这项操作。这并不是建立子类的问题,而是进程的地址空间边界的问题。如果能将你的子类过程的代码放入进程A的地址空间,就可以方便地调用S e t Wi n d o w L o n g P t r函数,将进程A的地址传递给M y S u b c l a s s P r o c函数。我将这个方法称为将D L L“插入”进程的地址空间。有若干种方法可以用来进行这项操作。下面将逐个介绍它们
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者