C# p/invoke,从所有者绘制的列表框中读取数据

标签 c# c++ pinvoke ownerdrawn

我在外部应用程序 (America Online) 中有一个所有者绘制的列表框,我需要从中获取数据以构建组件以帮助人们提高其可用性。 (该实用程序将使某些事物的访问变得更加简单,等等)。

通知

我对 C++ 的了解很差。我是一名 C# 程序员。

我有问题列表框的 hWnd,但它似乎是所有者绘制的。使用 LB_GETTEXT 返回错误数据,我只是得到垃圾(它在我的调试器中呈现为一堆汉字)并且通过 LB_GETITEMDATA 返回大致相同。

我相信这是因为所有者绘制的列表框上面有图形。通过很多的挖掘,我过去发现其他人也遇到过这个问题。我发现了以下应该解决此问题的代码。然而事实并非如此。代码贴在下面,下面是问题。

void GetListItemData( HWND hListWnd, long index, char *outputResult )
{
    int result;
    DWORD processID;
    HANDLE hProcess;
    char *itemData;
    char sDataRead[5];
    DWORD bytes;
    DWORD lListItemHold, lListItemDataHold;
    *outputResult=0;

    if( hListWnd )
    {
        GetWindowThreadProcessId( hListWnd, &processID );

        hProcess=OpenProcess( 0x10|0xf0000|PROCESS_VM_READ, 0, processID );

        if( hProcess )
        {
            lListItemHold=(DWORD)SendMessage( hListWnd, LB_GETITEMDATA, index-1, 0 );
            lListItemHold=lListItemHold+24;

            result=ReadProcessMemory( hProcess, (void *)lListItemHold, &sDataRead, 4, &bytes );
            if( !result )
            {
                RaiseWinErr();
            }

            memcpy( &lListItemDataHold, &sDataRead, 4 );
            lListItemDataHold=lListItemDataHold+6;

            ReadProcessMemory( hProcess, (void *)lListItemDataHold, outputResult, 16, &bytes );

            CloseHandle( hProcess );
        }
    }
}

我的理解虽然有限,但lListItemHold=lListItemHold+24 试图解释 ListBox 中的任何“结构”并传递它的前 24 个字节,然后返回什么遗迹。但是,这似乎对我不起作用。

任何人都可以阐明我可以尝试的事情吗?我知道我正在捕获救命稻草。我在 C# 中对此进行编码,因此使用 p/invoke 使用此函数,如下所示;

    [DllImport("GetListItemData.dll", CallingConvention = CallingConvention.Cdecl)]
    internal static extern void RetrieveListItem(
        System.IntPtr hWnd,
        System.Int32 index,
        [MarshalAs(UnmanagedType.LPArray)]byte[] buffer
    );

    [DllImport("GetListItemData.dll", CallingConvention = CallingConvention.Cdecl)]
    internal static extern void RetrieveListItem(
        System.IntPtr hWnd,
        System.Int32 index,
        [MarshalAs(UnmanagedType.LPTStr)]System.Text.StringBuilder buffer
    );

最佳答案

我有两篇关于这个主题的博文

http://taylorza.blogspot.com/2009/08/archive-hacking-my-way-across-process.html http://taylorza.blogspot.com/2010/06/crossing-process-boundary-with-net.html

然而,这些是针对 ListView 控件的,但您可能想看一下代码。第二篇文章是使用 P/Invoke 在 .NET 中实现这一点。

1- 为什么要向 lListItemHold 添加 24?

2- 你确定 lListItemhold 是一个指向字符串的指针吗,它可能是应用程序的一些内部结构。

关于C# p/invoke,从所有者绘制的列表框中读取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4680795/

相关文章:

c# - 推送 bin/js 文件后,Servicestack 丢失 session ,直到缓存清除

c++ - 无法让 ios::beg 返回到文件开头

c# - 检测事件 RDP session

.net - 检测从 .NET 调用的调用 dll 的崩溃

c# - 从资源文件中读取字符串并以编程方式编辑它

c# - 在通用 Windows 平台中播放声音

c# - DataContractSerializer 序列化到特定的 xml 节点

c++ - 如何在删除 en 元素(双 for 循环)后正确指向 std::list?

c++ - 使用 c++/openssl 解密带有密码的文件

c# - StringBuilder 编码导致 PInvokeStackImbalance 异常