如何子类化 Windows 资源管理器窗口
我想像这样更改 explorer.exe 的 listview 的颜色
我通过 GetTopWindow 获取了 listview 窗口的句柄功能和他的家人。
为了子类化 explorer.exe 的列表视图窗口,我通过以下代码将 dll 代码注入到资源管理器中。
SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstDll,
dwExplorerListviewThreadId);
explorer.exe 很好地加载了我的 dll。 我在注入的代码中通过 SetClassLongPtr(对于全局子类)对窗口过程进行了子类化。
SetClassLongPtr 返回成功,但我的子类函数(SubclassProc) 只接收 WM_CREATE WM_DESTROY 和 WM_MOVE 消息。怎么了?我期望得到WM_NOTIFY 和 NM_CUSTOMDRAW。
I want to change color of listview of explorer.exe like this
I got the handle of listview window by GetTopWindow function and his family.
To subclass listview window of explorer.exe, I injected my dll code to explorer by following code.
SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstDll,
dwExplorerListviewThreadId);
My dll is loaed by explorer.exe well.
And I subclassed the window procedure by SetClassLongPtr(for global subclass) in injected code.
SetClassLongPtr returns success but my subclass function(SubclassProc) receives only WM_CREATE WM_DESTROY and WM_MOVE messages. What's wrong? I expected to get WM_NOTIFY and NM_CUSTOMDRAW.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题在于,这首先不是一个 ListView;而是一个 ListView。相反,它使用 Microsoft 内部的“DirectlUI”框架,该框架在资源管理器中的多个位置使用。它不使用任何公共控制消息,例如 NM_CUSTOMDRAW。几乎没有合理的方法来改变它使用的颜色。
(此外,通常最好使用 SetWindowLongPtr 而不是 SetClassLongPtr 来子类化 HWND:SetClassLong 只会更改用于创建新窗口的基础模板,但最终可能不会更改基于该模板的任何实例。并且您不应该使用相同的函数 - GetMsgProc - 对于钩子回调和子类 proc,它们需要以不同的方式处理消息,钩子回调需要调用 CallNextHookEx,而子类 proc 需要使用原始 wndproc 调用 CallWindowProc,但是这些都不重要,因为该控件首先不是 ListView...)
The problem is that this is not a ListView in the first place; it's instead using Microsoft's internal "DirectlUI" framework, which is used in several places in explorer. It doesn't use any of the Common Control messages such as NM_CUSTOMDRAW. There's pretty much no reasonable way to change the colors it uses.
(Also, generally it's best to use SetWindowLongPtr instead of SetClassLongPtr for subclassing a HWND: SetClassLong only changes the underlying template that is used for creating new windows, but may not end up changing any instances that were based on that. And you should not be using the same function - GetMsgProc - for both the hook callback and the subclass proc; they need to handle the message in different ways, the hook callback needs to call CallNextHookEx while the subclass proc needs to call CallWindowProc with the original wndproc. But none of this really matters since the control isn't a ListView in the first place...)
我认为并假设操作系统对 explorer.exe 进程有特殊的保护,因为否则它将成为恶意代码的简单目标,或者只是认为它们比实际更重要的应用程序(如果有些人坚持放回一个每次启动应用程序时,他们都会在桌面上显示一个快捷方式,想象一下,当他们能够访问 explorer.exe(shell 中的所有内容)时他们会做什么。
编辑:我对这个问题很感兴趣并做了一些更多的研究,我认为有一个更平凡的原因,请参阅http://blogs.msdn.com/b/oldnewthing/archive/2005/09/07/461912.aspx。 (基本上:explorer.exe是窗口管理器,因此当它收到某些消息时还不知道消息路由,这就是为什么它们不能被消息挂钩拦截)。
I think and suppose that the OS has special protections for the explorer.exe process, because otherwise it would be an easy target for malicious code or just applications that think they are more important than they actually are (if some people insist on putting back a shortcut on their desktop every time you start the application, imagine what they would do when they had this sort of access to explorer.exe - everything in the shell).
EDIT: I was intrigued by the question and did some more research, I think there is a more mundane reason, see http://blogs.msdn.com/b/oldnewthing/archive/2005/09/07/461912.aspx. (basically: explorer.exe is the window manager so doesn't know about message routing yet when it receives certain messages, which is why they can't be intercepted with message hooks).