5

我正在与一位希望为旧版应用程序添加功能的客户合作。该应用程序(其供应商无用)具有 Windows 窗体 UI。我的客户想要的是当用户单击应用程序中的一条信息时触发此应用程序之外的某些功能。

我已经为另一个客户看到了一个简单的版本。在这种情况下,有一个应用程序由一个表单组成,该表单使用SetWindowPos. 当用户单击此表单上的按钮时,应用程序会找到旧应用程序的窗口并从窗口的标题中获取信息。这很不雅 - 即使旧版应用程序没有打开,这个浮动按钮也永远不会消失 - 但它可以工作。

我想知道是否可以使用具有Topmost属性集的无边框透明 WPF 窗口来执行类似的操作。我正在考虑的应用程序将分析旧应用程序窗口中的内容并定义热点列表。它会拦截和处理热点中的任何鼠标点击,并将所有剩余的鼠标点击传递给旧版应用程序。

我对 Windows API 的经验并不丰富,所以我不知道实现这种功能是否简单(甚至可能)。我突然想到,如果我正在编写反恶意软件工具,我想到的应用程序正是我试图削弱的那种东西。

如果这实际上是一个可行的项目,那么最好的方法是什么?我应该注意哪些意想不到的问题?

4

5 回答 5

3

这可以在没有任何技巧的情况下通过 WH_CALLWNDPROC和/或 WH_GETMESSAGE钩子覆盖按钮来完成。

于 2011-04-20T19:02:52.190 回答
1

在我看来,子类化是您正在寻找的。

当创建 Windows 应用程序时,它会生成一个窗口,然后将子窗口添加到该窗口(子窗口称为控件,其行为与 Windows 完全相同!它们可以是按钮、文本区域等...)。

每个窗口都有一个 Window 过程,每次用户/程序与您的窗口交互时,您的窗口过程都会收到一条包含交互信息的消息。很多时候,控件将与其父级共享一个窗口过程,并且在该窗口过程中,代码根据消息所描述的窗口/控件的 ID (hwnd) 确定要执行的操作 - 也就是说:“关闭如果“单击”消息描述了退出按钮控件,则程序。如果“单击”消息描述父窗口,则不执行任何操作。”。

要了解有关 Windows 的更多信息,请查看此处:http: //msdn.microsoft.com/en-us/library/aa383738%28v=vs.85%29.aspx

子类化是拦截和/或捕获发往另一个 Window 过程的消息的过程。它通常用作扩展第三方应用程序的控件和窗口行为的一种方式。可以使用DLLGetWindowLong()SetWindowLong()CallWindowProcedure()和您自己的自定义窗口过程对另一个进程进行子类化。这很容易——这就是你要做的事情:

  • 找到您希望使用子类化的目标窗口FindWindow()
  • 获取上一个窗口过程并存储它。

WNDPROC wpOrigEditProc = GetWindowLong(hTargetWnd, GWL_WNDPROC)

  • 用你自己的覆盖窗口过程。

SetWindowLong(hTargetWnd, GWL_WNDPROC, HookWndProcedure);

然后,当您卸载时,再次恢复旧的窗口程序。Window 过程是你所有魔法发生的地方。您将能够在该函数内部决定您希望处理哪些消息以及希望将哪些消息传递给旧窗口过程。这是一个示例窗口过程:

LRESULT APIENTRY HookWndProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 
    if(hwnd == hTargetWndButton_OK) {
        // This is the button we wish to intercept... do some processing, then send it back to Windows
        return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    } else {
        // Allow the message to pass through to the original application's window procedure.
        return CallWindowProc(wpOrigEditProc, hwnd, uMsg, 
            wParam, lParam); 
    }
} 

`

然后,诀窍是将您的 DLL 加载到目标进程中。我相信最好的方法是在应用程序中添加一个指向您的 DLL 的导入条目,因为无论如何应用程序和您的 DLL 都应该捆绑在一起。要添加导入,请使用 CFF Explorer!

我相信您会有更多问题,因为可能缺少一些信息。我将尝试回答我的帖子中出现的更多问题,但如果我没有立即回复,请阅读上面的 MSDN 链接 :D。希望这对您来说是一次很棒的学习经历:)

于 2011-04-28T23:58:47.640 回答
1

我肯定会尝试UI 自动化。它可能不起作用,但至少,它应该很容易尝试。而且,在大多数情况下,如果它不起作用,则意味着不会有任何其他“简单”的方法。

UI 自动化的根源在于为残疾人提供的辅助技术,这在大多数情况下是我们想要对我们不拥有的应用程序做的事情:从外部应用程序做事,而不能真正做到“标准方式” .

它在逻辑上也具有事件的概念,请参阅此处的官方文档: UI 自动化事件概述

于 2011-04-24T07:02:03.317 回答
0

davids 建议的替代方法是使用GetWindowLong,SetWindowLongCallWindowProc挂钩应用程序窗口 proc,imo 它比使用“windows hooking”方法简单一些,但它仍然可以通过该方法挂钩和/或再次子类化。有关一个简短示例,请参见在 msdn 上对窗口进行子类化:http: //msdn.microsoft.com/en-us/library/ms633570 (v=vs.85).aspx#subclassing_window

于 2011-04-24T06:22:52.343 回答
0

检查diz:http ://www.autohotkey.com/

它是可编写脚本的,可以读取窗口标题等。(当我使用 MS-Windows 时,我编写了一个小脚本,它会弹出一个包含项目价格和 p+p 成本总和的窗口,这些值被解析来自 ebay 网页的选择。另外,我已将其更改为我的货币。所以,我刚刚标记了商品的价格和 p+p,按下一个键,瞧。)

于 2011-04-30T15:56:29.723 回答