如何在 c# 中使用 user32.dll 从类“ThunderRT6ListBox”的窗口中检索值

本文关键字:ThunderRT6ListBox 从类 检索 窗口 dll user32 | 更新日期: 2023-09-27 18:31:47

我正在尝试从Windows中的外部桌面应用程序中检索信息。

我知道如何从

文本框中提取文本(类"编辑"),但我不知道如何从类名为"ThunderRT6ListBox"和"ThunderRT6ComboBox"的控件中提取值。我该怎么做?

我有以下代码从文本框中提取文本:

public static class ModApi
{
    [DllImport("user32.dll", EntryPoint = "FindWindowA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
    [DllImport("user32.dll", EntryPoint = "SendMessageTimeout", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern uint SendMessageTimeoutText(IntPtr hWnd, int Msg, int countOfChars, StringBuilder text, uint flags, uint uTImeoutj, uint result);
    [DllImport("user32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    static internal extern bool EnumChildWindows(IntPtr hWndParent, funcCallBackChild funcCallBack, IntPtr lParam);
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, StringBuilder lParam);
    const int LB_GETCOUNT = 0x018B;
    const int LB_GETTEXT = 0x0189;
    public static string GetText(IntPtr hwnd)
    {
        var text = new StringBuilder(1024);
        if (SendMessageTimeoutText(hwnd, 0xd, 1024, text, 0x2, 1000, 0) != 0)
        {
            return text.ToString();
        }
        return "";
    }        
}

public foo()
{
     IntPtr value = new IntPtr(0x019C086A); //ID locate using Spy++
     String caption = ModApi.GetText(value);
}

更新 1:

从列表框读取的方法:

    public static List<string> GetListBoxContents(IntPtr listBoxHwnd)
    {
        int cnt = (int)SendMessage(listBoxHwnd, LB_GETCOUNT, IntPtr.Zero, null);
        List<string> listBoxContent = new List<string>();
        for (int i = 0; i < cnt; i++)
        {
            StringBuilder sb = new StringBuilder(256);
            IntPtr getText = SendMessage(listBoxHwnd, LB_GETTEXT, (IntPtr)i, sb);
            listBoxContent.Add(sb.ToString());
        }
        return listBoxContent;
    }

更新 2:

从组合框读取的方法:

    public static List<string> GetComboBoxContents(IntPtr cbBoxHwnd)
    {
        int cnt = (int)SendMessage(cbBoxHwnd, CB_GETCOUNT, IntPtr.Zero, null);
        List<string> listBoxContent = new List<string>();
        for (int i = 0; i < cnt; i++)
        {
            //int txtLength = SendMessage(cbBoxHwnd, CB_GETLBTEXTLEN, i, 0); 
            StringBuilder sb = new StringBuilder(256);
            IntPtr getText = SendMessage(cbBoxHwnd, CB_GETLBTEXT, (IntPtr)i, sb);
            listBoxContent.Add(sb.ToString());
        }
        return listBoxContent;
    }

如何在 c# 中使用 user32.dll 从类“ThunderRT6ListBox”的窗口中检索值

您正在处理亿万年前的 VB6 应用程序。"Thunder"是VB产品/项目的内部名称(微不足道的旁注)。

比你意识到的更近。如果您有 HWND 控件,我认为您这样做:

  1. 使用该 HWND 调用发送消息,消息LB_GETCOUNT以获取列表中的项目数。
  2. 对于每个索引,使用 LB_GETTEXTLEN 和当前项索引调用 SendMessage 以获取文本的长度,然后相应地分配缓冲区。
  3. 再次调用 SendMessage,这次使用LB_GETTEXT消息、相同的项目索引(从零开始)以及对缓冲区的引用,这应该会得到每个项目的文本。

您可以考虑再给 SendMessage 一个只返回一个 int 的声明/别名,这应该会使其中一些调用更简单。

如果有机会,我会稍后用更具体的代码示例(或至少伪代码)来清理它,但我的印象是你已经走在正确的轨道上,可能只需要这个基本描述就可以完成剩下的工作。

祝你好运!

相关文章:
  • 没有找到相关文章