【问题标题】:getting the HWND for my own application in C在 C 中为我自己的应用程序获取 HWND
【发布时间】:2010-11-10 15:59:44
【问题描述】:

因为我找不到this 问题的答案,所以我对 MSDN 进行了更深入的研究,发现了 isChild()。它可能会给我另一个问题的答案。

现在,为了使用 isChild(),我需要传递要检查的父应用程序的 HWND,在本例中是我自己的应用程序。 如何获取自己应用的 HWND?

我不知道标题,因为它不断变化,所以我不能使用 FindWindow()。

谢谢

编辑:

由于不清楚,我将添加更多信息: 我没有创建一个窗口。我无权创建窗口。我的代码是一段代码,它与其他程序员正在编写的任何应用程序一起编译,我无法访问窗口的创建方式、标题或任何其他信息。 那么,如何将 HWND 获取到我正在运行的应用程序的“WINDOW”?

【问题讨论】:

    标签: c windows hwnd


    【解决方案1】:

    您的应用程序没有 HWND。窗户可以。一个应用程序可能没有窗口,也可能有很多窗口,因此没有“获取应用程序的 HWND”的通用功能。

    显而易见的解决方案是在拿到把手时抓住它。创建窗口时,将返回一个 HWND。存储它。

    【讨论】:

      【解决方案2】:

      使用 GetTopWindow() 和 GetNextWindow() 遍历窗口 z-order。

      但是,认为没有必要,但您可以使用 GetCurrentProcessId() 和 GetWindowThreadProcessId(),可能类似于以下内容会帮助你:

      HWND FindMyTopMostWindow()
      {
          DWORD dwProcID = GetCurrentProcessId();
          HWND hWnd = GetTopWindow(GetDesktopWindow());
          while(hWnd)
          {
              DWORD dwWndProcID = 0;
              GetWindowThreadProcessId(hWnd, &dwWndProcID);
              if(dwWndProcID == dwProcID)
                  return hWnd;            
              hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
          }
          return NULL;
       }
      

      【讨论】:

      • GetTopWindow() 始终返回 0。与 GetActiveWindow() 相同
      • 感谢重播,但如果使用 NULL 调用 GetTopWindow() 可能会返回另一个程序的顶部窗口(正如我在上一个问题中发现的那样),正如我在那个问题和这个我正在寻找有关我自己的应用程序和窗口的信息。
      • 因此您会找到最顶层的窗口——然后使用 GetNextWindow 以 z 顺序遍历窗口并将每个窗口与您的窗口进行比较。首先匹配的是你需要的。我以为可以这样做...
      • 您将 GetCurrentProcessId() 与返回的 id GetWindowThreadProcessId() 进行比较(如果匹配) -- 这是您的进程窗口。
      • 我不知道怎么做。你有机会给我看看吗?谢谢。
      【解决方案3】:

      你不能只抓住从 CreateWindow 返回的句柄吗?如果没有,为什么不呢?

      【讨论】:

      • 因为我没有创建窗口。 My my 是一个用别人的代码编译的模块。因此我无权创建窗口。现在,知道了这一点,我如何获取正在运行的应用程序窗口的 HWND?
      • 所以我假设你甚至无法访问窗口的消息泵?然后我唯一能想到的就是 EnumWindows,然后使用 GWL_HINSTANCE 参数调用 GetWindowLong 并将返回的 HINSTANCE 与从 GetModuleHandle 返回的进行比较。
      • 值得注意的是,您将获得与您的 HINSTANCE 相关的每个 HWND ...
      • 我一直在尝试这种方法,但是对于如此微不足道的事情让我很头疼......
      • 好吧,向编写窗口系统的人提出添加“GetHWND()”函数的请求肯定会更容易......
      【解决方案4】:

      大概您的代码被主应用程序代码调用,否则它有什么用?在这种情况下,我不明白为什么您的代码的 API 不能包含某种方式来通知您应用程序主窗口的句柄。

      【讨论】:

      • 因为不在设计文件中。就是这样。
      • 我的想法完全正确。这就是所有必要的。
      【解决方案5】:

      正如其他人已经指出的那样

      • 一般来说,一个应用程序可以有零个或多个顶级窗口。
      • 如果您自己创建窗口,您可以在某处记住 HWND。

      但也许您的代码在 DLL 中,因此您实际上并没有自己创建顶级窗口。那么该怎么办呢?

      我建议如下:

      • 使用EnumWindows 枚举所有顶级窗口。
      • 使用GetWindowLongPtr 获取每个顶级窗口的HINSTANCE。将此与应用程序的 HINSTANCE 进行比较,您可以使用 GetModuleHandle(NULL) 获得。如果它们相同,则您已找到主窗口。

      编辑:这是一些代码。原来你还必须使用IsWindowVisible,因为似乎有很多不可见的“帮助”窗口。

      HWND hwndMain;
      
      BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM lParam)
      {
          HINSTANCE hinst=(HINSTANCE)GetModuleHandle(NULL);
      
          if((HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE)==hinst &&
              IsWindowVisible(hwnd))
          {
              hwndMain=hwnd;
              return FALSE;
          }
          else
              return TRUE;
      }
      

      然后在你想找到窗口的地方:

      hwndMain=NULL;
      EnumWindows(EnumWindowProc, 0);
      

      在此之后,hwndMain 应该包含窗口的句柄,如果不存在则 NULL

      使用EnumWindows 有点繁琐,但建议不要在循环中调用GetWindow,因为正如 MSDN 指出的那样:“调用 GetWindow 来执行此任务的应用程序可能会陷入无限循环或引用一个被毁坏的窗户。”

      【讨论】:

      • 谢谢。看起来需要很多代码才能得到如此简单的东西。你有样品吗?
      【解决方案6】:

      您可以在调用 user32.dll 的线程中注入 DLL http://msdn.microsoft.com/en-us/library/ms821625.aspx

      【讨论】:

        【解决方案7】:

        这对我来说已经很旧了,但是 IIRC 你应该在窗口 proc 中接收 HWND 作为参数。您可以在开始时将其保存在全局变量中。

        【讨论】:

        • 实际上,与其将其存储为全局,不如将其传递给它,或者将指向另一个结构的指针作为 CreateWindowEX 的最后一个参数。然后,该指针将在 WM_CREATE 消息期间可供 Windows 过程使用。
        【解决方案8】:

        你的 windows 类名呢? 窗口创建总是不同吗? 如果没有,您仍然可以使用 FindWindow()。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-10
          • 2013-01-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-25
          相关资源
          最近更新 更多