📄 listviewextender.cs
字号:
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace ListViewToolTip
{
/// <summary>
/// Summary description for ListViewExtender.
/// </summary>
public class ListViewExtender
{
protected ListView listView;
protected IntPtr handle;
public ListViewExtender(ListView listView)
{
this.listView = listView;
this.listView.Capture = true;
this.handle = this.listView.Handle;
this.listView.Capture = false;
}
public HitItem GetItemAt(int x, int y)
{
HitItem hitItem = new HitItem();
// Init LVHITTESTINFO structure
LVHITTESTINFO hitTextInfo = new LVHITTESTINFO();
hitTextInfo.x = x;
hitTextInfo.y = y;
hitTextInfo.flags = LVHT_ONITEM;
// Allocate native memory
IntPtr pointer = AllocHGlobal(Marshal.SizeOf(hitTextInfo));
// Copy LVHITTESTINFO structure to the memory pointer
Marshal.StructureToPtr(hitTextInfo, pointer, false);
// Retreive item/subitem indexes
SendMessage(handle, LVM_SUBITEMHITTEST, 0, pointer);
hitTextInfo = (LVHITTESTINFO)Marshal.PtrToStructure(pointer, typeof(LVHITTESTINFO));
FreeHGlobal(pointer);
hitItem.ItemIndex = hitTextInfo.iItem;
hitItem.SubItemIndex = hitTextInfo.iSubItem;
return hitItem;
}
public Rectangle GetItemRectangle(int itemIndex, int subItemIndex)
{
RECT rect = new RECT();
rect.left = 2;
rect.top = subItemIndex;
// Retreive item's rectangle
SendMessage(handle, LVM_GETSUBITEMRECT, itemIndex, ref rect);
// Convert to the screen coordinates
Rectangle rc = listView.RectangleToScreen(new Rectangle(rect.left, rect.top - 26, rect.right - rect.left, rect.bottom - rect.top));
return rc;
}
private static IntPtr AllocHGlobal(int cb)
{
IntPtr ptr = LocalAlloc(LPTR, (uint)cb);
if (ptr == IntPtr.Zero)
{
throw new OutOfMemoryException();
}
return ptr;
}
private static void FreeHGlobal(IntPtr hGlobal)
{
if (hGlobal != IntPtr.Zero)
LocalFree(hGlobal);
}
#region P/Invokes
private const int GMEM_FIXED = 0x0000;
private const int LMEM_MOVEABLE = 2;
private const int LMEM_ZEROINIT = 0x0040;
private const int LPTR = (GMEM_FIXED | LMEM_ZEROINIT);
[DllImport("coredll.dll", EntryPoint = "LocalAlloc", SetLastError = true)]
static extern IntPtr LocalAlloc(uint uFlags, uint Bytes);
[DllImport("coredll.dll", EntryPoint = "LocalReAlloc", SetLastError = true)]
static extern IntPtr LocalReAllocCE(IntPtr hMem, int uBytes, int fuFlags);
[DllImport("coredll.dll", EntryPoint = "LocalFree", SetLastError = true)]
static extern IntPtr LocalFree(IntPtr hMem);
[DllImport("coredll.dll")]
static extern IntPtr GetCapture();
[DllImport("coredll.dll", SetLastError = true)]
static extern int SendMessage(IntPtr hwnd, int msg, int wParam, ref LVHITTESTINFO rect);
[DllImport("coredll.dll", SetLastError = true)]
static extern int SendMessage(IntPtr hwnd, int msg, int wParam, IntPtr lParam);
[DllImport("coredll.dll", SetLastError=true)]
static extern int SendMessage(IntPtr hwnd, int msg, int wParam, ref RECT rect);
const int LVM_FIRST = 0x1000;
const int LVM_GETITEMRECT = (LVM_FIRST + 14);
const int LVM_HITTEST = (LVM_FIRST + 18);
const int LVM_GETSUBITEMRECT = (LVM_FIRST + 56);
const int LVM_SUBITEMHITTEST = (LVM_FIRST + 57);
const int LVHT_NOWHERE = 0x0001;
const int LVHT_ONITEMICON =0x0002;
const int LVHT_ONITEMLABEL = 0x0004;
const int LVHT_ONITEMSTATEICON = 0x0008;
const int LVHT_ONITEM = (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON);
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
private struct POINT
{
public int x;
public int y;
}
private struct LVHITTESTINFO
{
//public POINT point;
public int x;
public int y;
public int flags;
public int iItem;
public int iSubItem;
}
#endregion
public struct HitItem
{
public int ItemIndex;
public int SubItemIndex;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -