LVM_GETCOLUMN 只有 returns 第一列的信息
LVM_GETCOLUMN only returns information about the first column
几天前,我在这里有一个关于函数 "LVM_GETCOLUMN" 的问题,该函数用于获取 syslistview32
中列的文本(请在此处找到此问题:)。
感谢这里的一位用户,我做到了运行。后来我意识到,这个功能只为我提供了第一列的文本。
有谁知道,LV_COLUMN 结构中的哪个参数负责定义目标列?我尝试了 iOrder
和 iSubItem
但无论我更改哪个参数(或者如果我同时更改两者)都没有关系,我总是得到第一列的文本 header。这是我正在使用的代码:
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
struct LV_COLUMN
{
public System.Int32 mask;
public System.Int32 fmt;
public System.Int32 cx;
public System.IntPtr pszText;
public System.Int32 cchTextMax;
public System.Int32 iSubItem;
public System.Int32 iImage;
public System.Int32 iOrder;
}
public static string GetListViewColumn(System.IntPtr hwnd, uint processId, int Column)
{
const int dwBufferSize = 2048;
const int LVM_FIRST = 0x1000;
const int LVM_GETCOLUMNA = LVM_FIRST + 25;
const int LVM_GETCOLUMNW = LVM_FIRST + 95;
const int LVCF_FMT = 0x00000001;
const int LVCF_TEXT = 0x00000004;
int bytesWrittenOrRead = 0;
LV_COLUMN lvCol;
string retval;
bool bSuccess;
System.IntPtr hProcess = System.IntPtr.Zero;
System.IntPtr lpRemoteBuffer = System.IntPtr.Zero;
System.IntPtr lpLocalBuffer = System.IntPtr.Zero;
try
{
lvCol = new LV_COLUMN();
lpLocalBuffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(dwBufferSize);
hProcess = OpenProcess(Win32ProcessAccessType.AllAccess, false, processId);
if (hProcess == System.IntPtr.Zero)
throw new System.ApplicationException("Failed to access process!");
lpRemoteBuffer = VirtualAllocEx(hProcess, System.IntPtr.Zero, dwBufferSize, Win32AllocationTypes.MEM_COMMIT, Win32MemoryProtection.PAGE_READWRITE);
if (lpRemoteBuffer == System.IntPtr.Zero)
throw new System.SystemException("Failed to allocate memory in remote process");
lvCol.mask = LVCF_TEXT;
lvCol.pszText = (System.IntPtr)(lpRemoteBuffer.ToInt32() + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN)));
lvCol.cchTextMax = 500;
lvCol.iOrder = Column;
lvCol.iSubItem = Column;
bSuccess = WriteProcessMemoryGETCOLUMN(hProcess, lpRemoteBuffer, ref lvCol, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN)), out bytesWrittenOrRead);
if (!bSuccess)
throw new System.SystemException("Failed to write to process memory");
SendMessage(hwnd, LVM_GETCOLUMNW, System.IntPtr.Zero, lpRemoteBuffer);
bSuccess = ReadProcessMemory(hProcess, lpRemoteBuffer, lpLocalBuffer, dwBufferSize, out bytesWrittenOrRead);
if (!bSuccess)
throw new System.SystemException("Failed to read from process memory");
retval = System.Runtime.InteropServices.Marshal.PtrToStringUni((System.IntPtr)(lpLocalBuffer.ToInt32() + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN))));
}
finally
{
if (lpLocalBuffer != System.IntPtr.Zero)
System.Runtime.InteropServices.Marshal.FreeHGlobal(lpLocalBuffer);
if (lpRemoteBuffer != System.IntPtr.Zero)
VirtualFreeEx(hProcess, lpRemoteBuffer, 0, Win32AllocationTypes.MEM_RELEASE);
if (hProcess != System.IntPtr.Zero)
CloseHandle(hProcess);
}
return retval; /*Always returns the name of the first column*/
}
问题出在 SendMessage 函数中。
"wparam" 参数是您要检索的列的索引
int index = 2;
SendMessage(hwnd, LVM_GETCOLUMNW, index, lpRemoteBuffer);
感谢 Laurijssen,这是工作代码:
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
struct LV_COLUMN
{
public System.Int32 mask;
public System.Int32 fmt;
public System.Int32 cx;
public System.IntPtr pszText;
public System.Int32 cchTextMax;
public System.Int32 iSubItem;
public System.Int32 iImage;
public System.Int32 iOrder;
}
public static string GetListViewColumn(System.IntPtr hwnd, uint processId, int Column)
{
const int dwBufferSize = 2048;
const int LVM_FIRST = 0x1000;
const int LVM_GETCOLUMNA = LVM_FIRST + 25;
const int LVM_GETCOLUMNW = LVM_FIRST + 95;
const int LVCF_FMT = 0x00000001;
const int LVCF_TEXT = 0x00000004;
int bytesWrittenOrRead = 0;
LV_COLUMN lvCol;
string retval;
bool bSuccess;
System.IntPtr hProcess = System.IntPtr.Zero;
System.IntPtr lpRemoteBuffer = System.IntPtr.Zero;
System.IntPtr lpLocalBuffer = System.IntPtr.Zero;
try
{
lvCol = new LV_COLUMN();
lpLocalBuffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(dwBufferSize);
hProcess = OpenProcess(Win32ProcessAccessType.AllAccess, false, processId);
if (hProcess == System.IntPtr.Zero)
throw new System.ApplicationException("Failed to access process!");
lpRemoteBuffer = VirtualAllocEx(hProcess, System.IntPtr.Zero, dwBufferSize, Win32AllocationTypes.MEM_COMMIT, Win32MemoryProtection.PAGE_READWRITE);
if (lpRemoteBuffer == System.IntPtr.Zero)
throw new System.SystemException("Failed to allocate memory in remote process");
lvCol.mask = LVCF_TEXT;
lvCol.pszText = (System.IntPtr)(lpRemoteBuffer.ToInt32() + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN)));
lvCol.cchTextMax = 500;
lvCol.iOrder = Column;
lvCol.iSubItem = Column;
bSuccess = WriteProcessMemoryGETCOLUMN(hProcess, lpRemoteBuffer, ref lvCol, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN)), out bytesWrittenOrRead);
if (!bSuccess)
throw new System.SystemException("Failed to write to process memory");
SendMessage(hwnd, LVM_GETCOLUMNW, (System.IntPtr)Column, lpRemoteBuffer);
bSuccess = ReadProcessMemory(hProcess, lpRemoteBuffer, lpLocalBuffer, dwBufferSize, out bytesWrittenOrRead);
if (!bSuccess)
throw new System.SystemException("Failed to read from process memory");
retval = System.Runtime.InteropServices.Marshal.PtrToStringUni((System.IntPtr)(lpLocalBuffer.ToInt32() + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN))));
}
finally
{
if (lpLocalBuffer != System.IntPtr.Zero)
System.Runtime.InteropServices.Marshal.FreeHGlobal(lpLocalBuffer);
if (lpRemoteBuffer != System.IntPtr.Zero)
VirtualFreeEx(hProcess, lpRemoteBuffer, 0, Win32AllocationTypes.MEM_RELEASE);
if (hProcess != System.IntPtr.Zero)
CloseHandle(hProcess);
}
return retval;
}
几天前,我在这里有一个关于函数 "LVM_GETCOLUMN" 的问题,该函数用于获取 syslistview32
中列的文本(请在此处找到此问题:
感谢这里的一位用户,我做到了运行。后来我意识到,这个功能只为我提供了第一列的文本。
有谁知道,LV_COLUMN 结构中的哪个参数负责定义目标列?我尝试了 iOrder
和 iSubItem
但无论我更改哪个参数(或者如果我同时更改两者)都没有关系,我总是得到第一列的文本 header。这是我正在使用的代码:
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
struct LV_COLUMN
{
public System.Int32 mask;
public System.Int32 fmt;
public System.Int32 cx;
public System.IntPtr pszText;
public System.Int32 cchTextMax;
public System.Int32 iSubItem;
public System.Int32 iImage;
public System.Int32 iOrder;
}
public static string GetListViewColumn(System.IntPtr hwnd, uint processId, int Column)
{
const int dwBufferSize = 2048;
const int LVM_FIRST = 0x1000;
const int LVM_GETCOLUMNA = LVM_FIRST + 25;
const int LVM_GETCOLUMNW = LVM_FIRST + 95;
const int LVCF_FMT = 0x00000001;
const int LVCF_TEXT = 0x00000004;
int bytesWrittenOrRead = 0;
LV_COLUMN lvCol;
string retval;
bool bSuccess;
System.IntPtr hProcess = System.IntPtr.Zero;
System.IntPtr lpRemoteBuffer = System.IntPtr.Zero;
System.IntPtr lpLocalBuffer = System.IntPtr.Zero;
try
{
lvCol = new LV_COLUMN();
lpLocalBuffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(dwBufferSize);
hProcess = OpenProcess(Win32ProcessAccessType.AllAccess, false, processId);
if (hProcess == System.IntPtr.Zero)
throw new System.ApplicationException("Failed to access process!");
lpRemoteBuffer = VirtualAllocEx(hProcess, System.IntPtr.Zero, dwBufferSize, Win32AllocationTypes.MEM_COMMIT, Win32MemoryProtection.PAGE_READWRITE);
if (lpRemoteBuffer == System.IntPtr.Zero)
throw new System.SystemException("Failed to allocate memory in remote process");
lvCol.mask = LVCF_TEXT;
lvCol.pszText = (System.IntPtr)(lpRemoteBuffer.ToInt32() + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN)));
lvCol.cchTextMax = 500;
lvCol.iOrder = Column;
lvCol.iSubItem = Column;
bSuccess = WriteProcessMemoryGETCOLUMN(hProcess, lpRemoteBuffer, ref lvCol, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN)), out bytesWrittenOrRead);
if (!bSuccess)
throw new System.SystemException("Failed to write to process memory");
SendMessage(hwnd, LVM_GETCOLUMNW, System.IntPtr.Zero, lpRemoteBuffer);
bSuccess = ReadProcessMemory(hProcess, lpRemoteBuffer, lpLocalBuffer, dwBufferSize, out bytesWrittenOrRead);
if (!bSuccess)
throw new System.SystemException("Failed to read from process memory");
retval = System.Runtime.InteropServices.Marshal.PtrToStringUni((System.IntPtr)(lpLocalBuffer.ToInt32() + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN))));
}
finally
{
if (lpLocalBuffer != System.IntPtr.Zero)
System.Runtime.InteropServices.Marshal.FreeHGlobal(lpLocalBuffer);
if (lpRemoteBuffer != System.IntPtr.Zero)
VirtualFreeEx(hProcess, lpRemoteBuffer, 0, Win32AllocationTypes.MEM_RELEASE);
if (hProcess != System.IntPtr.Zero)
CloseHandle(hProcess);
}
return retval; /*Always returns the name of the first column*/
}
问题出在 SendMessage 函数中。
"wparam" 参数是您要检索的列的索引
int index = 2;
SendMessage(hwnd, LVM_GETCOLUMNW, index, lpRemoteBuffer);
感谢 Laurijssen,这是工作代码:
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
struct LV_COLUMN
{
public System.Int32 mask;
public System.Int32 fmt;
public System.Int32 cx;
public System.IntPtr pszText;
public System.Int32 cchTextMax;
public System.Int32 iSubItem;
public System.Int32 iImage;
public System.Int32 iOrder;
}
public static string GetListViewColumn(System.IntPtr hwnd, uint processId, int Column)
{
const int dwBufferSize = 2048;
const int LVM_FIRST = 0x1000;
const int LVM_GETCOLUMNA = LVM_FIRST + 25;
const int LVM_GETCOLUMNW = LVM_FIRST + 95;
const int LVCF_FMT = 0x00000001;
const int LVCF_TEXT = 0x00000004;
int bytesWrittenOrRead = 0;
LV_COLUMN lvCol;
string retval;
bool bSuccess;
System.IntPtr hProcess = System.IntPtr.Zero;
System.IntPtr lpRemoteBuffer = System.IntPtr.Zero;
System.IntPtr lpLocalBuffer = System.IntPtr.Zero;
try
{
lvCol = new LV_COLUMN();
lpLocalBuffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(dwBufferSize);
hProcess = OpenProcess(Win32ProcessAccessType.AllAccess, false, processId);
if (hProcess == System.IntPtr.Zero)
throw new System.ApplicationException("Failed to access process!");
lpRemoteBuffer = VirtualAllocEx(hProcess, System.IntPtr.Zero, dwBufferSize, Win32AllocationTypes.MEM_COMMIT, Win32MemoryProtection.PAGE_READWRITE);
if (lpRemoteBuffer == System.IntPtr.Zero)
throw new System.SystemException("Failed to allocate memory in remote process");
lvCol.mask = LVCF_TEXT;
lvCol.pszText = (System.IntPtr)(lpRemoteBuffer.ToInt32() + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN)));
lvCol.cchTextMax = 500;
lvCol.iOrder = Column;
lvCol.iSubItem = Column;
bSuccess = WriteProcessMemoryGETCOLUMN(hProcess, lpRemoteBuffer, ref lvCol, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN)), out bytesWrittenOrRead);
if (!bSuccess)
throw new System.SystemException("Failed to write to process memory");
SendMessage(hwnd, LVM_GETCOLUMNW, (System.IntPtr)Column, lpRemoteBuffer);
bSuccess = ReadProcessMemory(hProcess, lpRemoteBuffer, lpLocalBuffer, dwBufferSize, out bytesWrittenOrRead);
if (!bSuccess)
throw new System.SystemException("Failed to read from process memory");
retval = System.Runtime.InteropServices.Marshal.PtrToStringUni((System.IntPtr)(lpLocalBuffer.ToInt32() + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LV_COLUMN))));
}
finally
{
if (lpLocalBuffer != System.IntPtr.Zero)
System.Runtime.InteropServices.Marshal.FreeHGlobal(lpLocalBuffer);
if (lpRemoteBuffer != System.IntPtr.Zero)
VirtualFreeEx(hProcess, lpRemoteBuffer, 0, Win32AllocationTypes.MEM_RELEASE);
if (hProcess != System.IntPtr.Zero)
CloseHandle(hProcess);
}
return retval;
}