从其他窗口的ListView项目窗口、项目、ListView

2023-09-02 21:47:42 作者:℡此男洧點⒉

我在做C#的一些项目。 我需要获得项目从的ListView 的窗口,它的手柄我做这样的事情

I'm doing some project on c#. I need to get i item from ListView window, handle of it I got by doing something like this

IntPtr par_hWnd = API.FindWindow(null, "Form1");
IntPtr child1 = API.FindWindowEx(par_hWnd, (IntPtr)0, null, null);

API 是我的静态类,有很多dllimports从user32.dll中 我能够拿到的项目数量在此的ListView:

API is my static class with lots of dllimports from "user32.dll" I am able to get count of items in this ListView:

IntPtr count = API.SendMessage(child1, API.LVM_GETITEMCOUNT, 0, 0);

现在我需要得到项目的文本,但结果却莫名其妙地必须放置在 LVITEM 结构,我不知道该怎么称呼 SendMessage函数正确,以及如何实施 LVITEM 。找不到实例C#。任何帮助?

Now i need to get the text of item, but the result somehow must be placed in the LVITEM Structure, I don't know how to call SendMessage correctly, and how to implement LVITEM in c#. Can't find examples for c#. Any help?

推荐答案

这是比人们想象的更困难。为了得到你想要的信息,你必须在相同的进程空间中包含的ListView 控件的应用程序执行$ ​​C $ C。你可以通过在目标进程是大到足以容纳 LVITEM 结构和字符串数据您预计要返回分配的内存块,然后移动的结构,目标进程。 .NET框架使事情变得相当容易一点上我们这里用的 元帅类。

This is more difficult than one might think. In order to get the information you're looking for, you have to execute the code in the same process space as the application containing the ListView control. You do that by allocating a block of memory in the target process that is large enough to hold the LVITEM structure and the string data you expect to be returned, then move that structure to the target process. The .NET Framework makes things quite a bit easier on us here with the Marshal class.

一旦你采取的考虑,这是声明的 LVITEM 结构和发送的 LVM_GETITEM 消息来控制使用的 SendMessage函数功能,你嫌。

Once you've taken that into account, it's a simple matter of declaring the LVITEM structure and sending the LVM_GETITEM message to the control using the SendMessage function, as you suspected.

// P/Invoke declarations

private const int LVM_FIRST = 0x1000;
private const int LVM_GETITEMCOUNT = LVM_FIRST + 4;
private const int LVM_GETITEM = LVM_FIRST + 75;
private const int LVIF_TEXT = 0x0001;

[DllImport("user32.dll"), CharSet = CharSet.Auto]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam,
                                         IntPtr lParam);

[StructLayoutAttribute(LayoutKind.Sequential)]
private struct LVITEM
{
    public uint mask;
    public int iItem;
    public int iSubItem;
    public uint state;
    public uint stateMask;
    public IntPtr pszText;
    public int cchTextMax;
    public int iImage;
    public IntPtr lParam;
}

然后你可以使用它像这样(假设 hListView 是一个有效的句柄的ListView 控制):

And then you would use it like this (assuming hListView is a valid handle to a ListView control):

// Declare and populate the LVITEM structure
LVITEM lvi = new LVITEM();
lvi.mask = LVIF_TEXT;
lvi.cchTextMax = 512;
lvi.iItem = 1;            // the zero-based index of the ListView item
lvi.iSubItem = 0;         // the one-based index of the subitem, or 0 if this
                          //  structure refers to an item rather than a subitem
lvi.pszText = Marshal.AllocHGlobal(512);

// Send the LVM_GETITEM message to fill the LVITEM structure
IntPtr ptrLvi = Marshal.AllocHGlobal(Marshal.SizeOf(lvi));
Marshal.StructureToPtr(lvi, ptrLvi, false);
SendMessage(hListView, LVM_GETITEM, IntPtr.Zero, ptrLvi);

// Extract the text of the specified item
string itemText = Marshal.PtrToStringAuto(lvi.pszText);