C++:如何为控制台应用程序设置新的wndProc?

13

如果我有一个控制台应用程序,并像这样设置了对它的句柄;

HWND hWnd = GetConsoleWindow();

那么我如何为窗口设置一个新的wndProc?
我尝试使用了

SetWindowLong(hWnd, GWL_WNDPROC, (LONG)conProc);

假设conProc已定义为:

LRESULT CALLBACK conProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_NCHITTEST:
            return HTCAPTION;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam );
}

但是它并不起作用,并在GetLastError()上显示“错误代码:5 - 拒绝访问”

我知道像这样修改控制台应用程序非常困难,因为它是一个csrss.exe应用程序,但我仍然想尝试一下。谢谢。


根据你的需求,你可能会发现Console项目很有用。 - Cheers and hth. - Alf
2
很有趣,因为我本来想说你可以获取与之关联的WNDCLASSEX并基于它创建自己的窗口,但事实证明获取WNDCLASSEX有点困难。GetClassInfoEx需要一个模块句柄,而获取该句柄很麻烦。即使是CreateToolhelp32Snapshot也明确说明不能与csrss.exe一起使用。 - chris
2个回答

16

我并不是真的在寻找一个“做不到”的答案,但你给了我一些有趣的链接,所以我点了个赞。我听说过有人能够做这种事情,我对他们是如何做到的很感兴趣。我进行了快速的谷歌搜索,找到了这个:http://www.codeforge.com/read/115608/CsrssHook.c__html - 看起来这是一个用于钩取CSRSS的示例代码。我想这可能是某种证明它可以做到的证据..? - user1219742
你所提到的示例实现了对目标进程的代码注入,这样你就可以在该进程中提供自己的 WndProc。如果你有足够的权限来钩取系统进程,那么这可能会起作用。但是,如果你使用 OpenProcess(PROCESS_ALL_ACCESS, ... 时遇到 ERROR_ACCESS_DENIED 错误,也不要感到惊讶。 - Roman R.
1
在Windows 7+中,控制台窗口由conhost.exe托管,该进程在客户端的安全上下文中运行,即在此情况下您拥有PROCESS_ALL_ACCESS - Eryk Sun

1
首先,SetWindowLong已被SetWindowLongPtr取代,您应该使用后者。
您是想更改自己的控制台窗口或另一个进程的WNDPROC吗?
根据MSDN文档:
GWL_WNDPROC -4 设置窗口过程的新地址。 如果窗口不属于调用线程所在的进程,则无法更改此属性。

6
他自己的控制台窗口属于另一个进程。 - Hans Passant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接