LVM_GETCOLUMN仅返回首列信息,如何指定目标列?
LVM_GETCOLUMN Only Returning First Column Text Hey there, I see the issue you're running into—let's break this down and get your code working properly.
The Core Mistake: You're Not Specifying the Target Column in SendMessage
The LVM_GETCOLUMN message doesn't use the iSubItem or iOrder fields in the LV_COLUMN struct to pick which column to retrieve. Instead, the target column index (0-based) is passed as the wParam argument to SendMessage.
In your current code, you're passing System.IntPtr.Zero for wParam, which defaults to column 0 (the first column)—that's why you always get the first column's text no matter what you set iSubItem or iOrder to.
What Each LV_COLUMN Field Actually Does
Let's clarify the fields you were tweaking, so you know when to use them:
iSubItem: This links the column to its corresponding subitem index in the list view items. For most standard list views, this matches the column index, but it's not used to select which column to fetch withLVM_GETCOLUMN.iOrder: This controls the display order of columns (e.g., if the user drags columns to reorder them). It doesn't specify which column you're retrieving—it just describes the column's position in the UI.
How to Fix Your Code
Update the SendMessage call to pass your Column parameter (as an IntPtr) as the wParam. Note: Make sure your Column value is 0-based. If your function expects a 1-based column number (e.g., passing 1 for the first column), you'll need to subtract 1 first.
Here's the corrected line:
SendMessage(hwnd, LVM_GETCOLUMNW, (IntPtr)Column, lpRemoteBuffer);
Additional Checks to Ensure Success
- Double-check that you're using the correct character set: You're using
LVM_GETCOLUMNW(wide Unicode) andPtrToStringUni, which is correct if the target list view uses Unicode. If it's an ANSI control, switch toLVM_GETCOLUMNAandPtrToStringAnsi. - Verify your column index is valid: Make sure
Columnis within the range of existing columns (0 tonumber of columns - 1). You can get the total number of columns withLVM_GETCOLUMNCOUNTif needed. - Simplify process permissions if needed: While
Win32ProcessAccessType.AllAccessworks, you can reduce it toPROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITEfor better security—those are the only permissions required for memory operations here.
Full Corrected Snippet (Relevant Part)
// ... existing code ... 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"); // Fix: Pass the target column index as wParam SendMessage(hwnd, LVM_GETCOLUMNW, (IntPtr)Column, lpRemoteBuffer); bSuccess = ReadProcessMemory(hProcess, lpRemoteBuffer, lpLocalBuffer, dwBufferSize, out bytesWrittenOrRead); // ... existing code ...
That should get you the correct column text instead of always returning the first one!
内容的提问来源于stack exchange,提问作者Jan021981

