Since USER32 messages were mentioned above, but the implementation was not given, and I just came across this when I needed to solve it, here is a working version using messaging with native code.
Here are some required elements enclosed in the NativeMethods private class:
private static class NativeMethods { private const int LVM_FIRST = 0x1000; private const int LVM_GETHEADER = LVM_FIRST + 31; private const int HDM_FIRST = 0x1200; private const int HDM_GETITEMRECT = HDM_FIRST + 7; private const int SB_HORZ = 0; private const int SB_VERT = 1; private const int SIF_POS = 0x0004; [StructLayout(LayoutKind.Sequential)] public class SCROLLINFO { public int cbSize = Marshal.SizeOf(typeof(NativeMethods.SCROLLINFO)); public int fMask; public int nMin; public int nMax; public int nPage; public int nPos; public int nTrackPos; } [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam); [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] public static extern IntPtr SendMessageGETRECT(IntPtr hWnd, int Msg, int wParam, ref RECT lParam); [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern bool GetScrollInfo(IntPtr hWnd, int fnBar, SCROLLINFO scrollInfo);
Here is the code that gets your location:
/// <summary> /// Get the location coordinate of the specified column header top/left corner /// </summary> /// <param name="oListView">ListView control to get the column header location from</param> /// <param name="iColumn">Column to find the location for</param> /// <param name="bAsScreenCoordinate">Whether the location returned is for the screen or the local ListView control</param> /// <returns>Location of column header or <see cref="Point.Empty"/> if it could not be retrieved</returns> public static Point GetColumnHeaderTopLeft(this ListView oListView, int iColumn, bool bAsScreenCoordinate) { if (oListView == null) { throw new ArgumentNullException(); } if ((iColumn < 0) || (iColumn >= oListView.Columns.Count)) { throw new ArgumentOutOfRangeException(); } // Get the header control rectangle IntPtr hndHeader = NativeMethods.GetHeaderControl(oListView); Rectangle oHeaderRect = NativeMethods.GetHeaderItemRect(hndHeader, iColumn); if (oHeaderRect.IsEmpty) { return Point.Empty; } // Get the scroll bar position to adjust the left int iScroll = NativeMethods.GetScrollPosition(oListView, true); // Create the local coordinate Point oLocation = new Point(oHeaderRect.Left - iScroll, oHeaderRect.Top); // Return the local or screen coordinate return bAsScreenCoordinate ? oListView.PointToScreen(oLocation) : oLocation; }
Cuppm source share