代码之家  ›  专栏  ›  技术社区  ›  zendar

将窗口附加到正在运行的应用程序

  •  0
  • zendar  · 技术社区  · 16 年前

    在一个重要的表单上,有一些字段,客户希望显示来自其他数据库的其他数据,并询问我是否可以在现有表单上“管道胶带”数据。

    我的第一个想法是构建应用程序,它将:

    • 在显示目标表单时收到通知时附加“某些”事件
    • 当目标表单上的字段发生更改时,在收到通知时附加“some”事件
    • 在覆盖目标窗体的小窗口中显示附加信息

    注-未计划重写ERP应用程序。

    1 回复  |  直到 16 年前
        1
  •  4
  •   Kevin Montrose    16 年前

    我将从一个纯粹的C&Win32的观点,因为我不知道Delphi或它的库。可以通过p/invoke将其转换为C#,但某些部分可能/将需要非托管。

    不保证 HWND 在屏幕上的每一个控制下)你都很不走运。这并不少见,所以是的。。。

    步骤1,注册一个窗口挂钩,监听目标进程创建的新窗口*:

    //dllHMod is an HMODULE that refers to the DLL containing ShellHookProc
    HHOOK hook = SetWindowsHookEx(WH_SHELL, ShellHookProc, dllHMod, 0);
    // error handling, stashing hook away for unregistering later, etc...
    
    LRESULT CALLBACK ShellHookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
      if(nCode < 0) return CallNextHookEx(NULL, nCode, wParam, lParam);
    
      if(nCode == HSHELL_WINDOWCREATED)
      {
        WindowCreate((HWND)wParam);
      }
    
      return 0;
    }
    

    WindowCreated(HWND) 如果正确的流程(通过 GetWindowThreadProcessId

    现在来看有趣的部分。没有可靠的方法来判断窗口何时完全构建,或何时完成渲染(有方法可以判断窗口何时开始渲染,但这并没有真正的帮助)。我的建议, 猜测

    要枚举子窗口(如果您对目标窗口了解得足够多,有更好的方法可以做到这一点;但我假设搜索是最简单的):

    //targetHWND is an HWND of one of the top-level windows you've found
    EnumChildWindows(targetHWND, ChildWindowCallback, NULL);
    //more code...
    
    BOOL ChildWindowCallback(HWND window, LPARAM ignored)
    {
      if(IsTargetWindow(window)) { /* Do something */ }
    
      return TRUE;
    }
    

    实施 IsTargetWindow GetWindowInfo ).

    一旦有了要监视的窗口,就可以使用 SetWindowLongPtr GWLP_WNDPROC 监视它接收的所有消息。这将需要代码注入(从而需要非托管代码),而且级别非常低。如果你能避免的话,我建议你不要这样做,但是由于缺乏来源。。。

    我认为这是一个不错的起点,但再一次 这将是非常痛苦的 如果可能的话。祝你好运

    EnumWindows .