【问题标题】:Enumerating Windows?枚举窗口?
【发布时间】:2013-04-15 00:03:21
【问题描述】:

我正在制作一个需要 Skype 窗口中的一些信息的应用程序,我找到了主窗口和子窗口。我使用 WM_GETTEXT 并在消息框中显示缓冲区。换了几次联系人后好像不行了。谁能猜猜为什么几秒钟后会中断?

case 2000:
  //Make options window here
  int len;
  char* buffer;
  HWND hWnd; //Main Window
  HWND chat; //Tconversation form, Caption is the contact's name.
  hWnd = FindWindow(L"tSkMainForm", NULL); //tSkMainForm is SKYPE
  chat = FindWindowEx(hWnd, NULL, L"TConversationForm", NULL); //GetWindow(hWnd,GW_CHILD);
  if (IsWindowVisible(chat)) {
    len = SendMessage(chat, WM_GETTEXTLENGTH, 0, 0);
    buffer = new char[len];
    SendMessageW(chat, WM_GETTEXT, (WPARAM) len + 1, (LPARAM) buffer);
    MessageBox(HWND_DESKTOP, (LPCWSTR) buffer, L"Testing", MB_OK);
  } else MessageBox(HWND_DESKTOP, L"We cannot find the window.", L"About Testing", MB_OK);
break;

所以只是给你一个事件的时间表,这就是发生的事情。

我将我的 DLL 注入 Skype,它会创建一个菜单,一切正常。当我按下新创建的按钮(ID 2000)时,我想获取联系人的姓名。 Spy++ 告诉我“TConversationForm”的标题是联系人的姓名。这适用于最初的几个联系人,但随后 Skype 崩溃。

我知道我可以使用 Skype API,但我更多地将其用作学习目的,而不是制作工作工具。

【问题讨论】:

  • 您是否尝试过在调试器中附加到 Skype,以便了解应用程序崩溃的位置?如果您的代码直接导致了崩溃,它应该进入调试器并直接将您带到文件中发生崩溃的行。
  • 我看到buffer = new char[len];匹配的delete[]在哪里?我建议你使用操作系统函数(例如HeapAlloc)代替注入代码,因为你不控制 Skype 使用的 C++ 运行时。
  • 使用无障碍界面。这就是他们的目的
  • @Ben Skype 不使用 C++ 运行时。这是一个德尔福应用程序。查看类名。
  • @cole 按钮的id根据q

标签: c++ c dll


【解决方案1】:

您似乎在谎报缓冲区的长度。您分配 len 个字符,然后说缓冲区的大小为 len+1。您需要分配 len+1 个字符。

Windows 上的 Skype 是一个 Delphi 应用程序,使用 VCL 控件构建。 VCL 使用的设计有时会导致在窗体的生命周期内重新创建窗口。换句话说,窗口句柄可以更改,您可能会留下一个陈旧的句柄。这是另一种似是而非的失败模式。

另一种可能的故障模式是,您正在以应用程序不知道的方式从非 GUI 线程中弄乱 GUI。很有可能在 VCL 背后添加一个菜单就足以导致失败。

您不应该将 HWND_DESKTOP 用作窗口所有者,而且您似乎泄漏了该文本缓冲区。

我认为你在这条道路上成功的几率很低。非常低。我建议您使用受支持的自动化界面。

【讨论】:

  • 好的,我已经解决了 len 问题(老实说,我没有看到这个问题,我已经注意到它是我将来需要解决的问题)。我还要让 DLL 创建自己的窗口。这样VCL就不会造成任何进一步的问题。
  • 由于五分钟后我无法编辑我的评论,我将在这里补充:我将如何确保我的句柄不会变坏?每次我需要它时,我会简单地重新找到窗口吗?据我所知,Skype 在任何时候都只有一个我正在寻找的类的实例(TConversationForm 类)。也感谢大家的帮助。
  • 是的,一次又一次地找到窗口就可以了。当然,再创造可能不会伤害你。但也许是。
  • 那么,对于我的 hWnd,由于我在 if 条件中定义了它,它是否会在每次运行时创建一个新的?如果我只是让菜单显示一个静态消息框(无内存分配),Skype 不会崩溃。所以我认为这是/是一个内存错误。
  • 如果你有一个陈旧的窗口句柄,你应该不会崩溃。只是 Win32 API 调用会失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-17
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多