【问题标题】:C++: How to set a new wndProc for a console application?C++:如何为控制台应用程序设置新的 wndProc?
【发布时间】:2012-11-02 12:36:32
【问题描述】:

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

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 project 很有用。
  • 这很有趣,因为我要说你可以抓住与之关联的WNDCLASSEX 并根据它创建自己的窗口,但事实证明抓住WNDCLASSEX 有点困难. GetClassInfoEx 需要一个模块句柄,而获取该句柄很烦人。甚至CreateToolhelp32Snapshot 也明确表示不能将其与 csrss.exe 一起使用。

标签: c++ winapi console access-denied wndproc


【解决方案1】:

首先SetWindowLong被SetWindowLongPtr取代,你应该使用那个函数。

您是否尝试更改您自己的控制台窗口或其他进程的 WNDPROC?

来自 MSDN 文档:

GWL_WNDPROC -4 Sets a new address for the window procedure. You cannot change this attribute if the window does not belong to the same process as the calling thread.

【讨论】:

  • 他自己的控制台窗口属于另一个进程,
【解决方案2】:

虽然给人的印象是控制台窗口属于您的进程(与其他窗口一样),但它实际上由CSRSS 系统进程托管,并且它的 WndProc 就在那里。这使您无法对窗口进行子类化并在您的进程中提供您自己的 WndProc。

一些相关阅读:

【讨论】:

  • 我并不是真的在寻找“无法完成”的答案,但你确实给了我一些有趣的链接,所以我支持你。我听说有人能够做这种事情,我对他们是如何做到的很感兴趣。我做了一个快速的谷歌搜索,我发现了这个:codeforge.com/read/115608/CsrssHook.c__html - 这似乎是一个用于连接 CSRSS 的示例代码。我想这将是可以做到的某种证明..?
  • 您提到的示例将代码注入到目标进程中,因此您可以在该进程中提供自己的WndProc ...如果您有足够的权限来挂钩系统进程,这可能会奏效,然而。为OpenProcess(PROCESS_ALL_ACCESS, ... 获得ERROR_ACCESS_DENIED 不要感到惊讶。
  • 在 Windows 7+ 中,控制台窗口由 ​​conhost.exe 托管,它在客户端的安全上下文中运行,即在这种情况下您有 PROCESS_ALL_ACCESS
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
相关资源
最近更新 更多