------ #### ryControls V2.1.2101.1201 - *.[更新]内置的ObjectListView从1.13更新到2.9.1版本,并对主要属性进行汉化。 - *.[修复]修复新版ObjectListView选中项有筛选结果时,筛选结果白色字体看不清的BUG。 - *.[改进]TextBoxEx2默认事件改为TextChanged2。
1227 lines
52 KiB
C#
1227 lines
52 KiB
C#
/*
|
|
* NativeMethods - All the Windows SDK structures and imports
|
|
*
|
|
* Author: Phillip Piper
|
|
* Date: 10/10/2006
|
|
*
|
|
* Change log:
|
|
* v2.8.0
|
|
* 2014-05-21 JPP - Added DeselectOneItem
|
|
* - Added new imagelist drawing
|
|
* v2.3
|
|
* 2006-10-10 JPP - Initial version
|
|
*
|
|
* To do:
|
|
*
|
|
* Copyright (C) 2006-2014 Phillip Piper
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com.
|
|
*/
|
|
|
|
using System;
|
|
using System.Drawing;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows.Forms;
|
|
|
|
namespace BrightIdeasSoftware
|
|
{
|
|
/// <summary>
|
|
/// Wrapper for all native method calls on ListView controls
|
|
/// </summary>
|
|
internal static class NativeMethods
|
|
{
|
|
#region Constants
|
|
|
|
private const int LVM_FIRST = 0x1000;
|
|
private const int LVM_GETCOLUMN = LVM_FIRST + 95;
|
|
private const int LVM_GETCOUNTPERPAGE = LVM_FIRST + 40;
|
|
private const int LVM_GETGROUPINFO = LVM_FIRST + 149;
|
|
private const int LVM_GETGROUPSTATE = LVM_FIRST + 92;
|
|
private const int LVM_GETHEADER = LVM_FIRST + 31;
|
|
private const int LVM_GETTOOLTIPS = LVM_FIRST + 78;
|
|
private const int LVM_GETTOPINDEX = LVM_FIRST + 39;
|
|
private const int LVM_HITTEST = LVM_FIRST + 18;
|
|
private const int LVM_INSERTGROUP = LVM_FIRST + 145;
|
|
private const int LVM_REMOVEALLGROUPS = LVM_FIRST + 160;
|
|
private const int LVM_SCROLL = LVM_FIRST + 20;
|
|
private const int LVM_SETBKIMAGE = LVM_FIRST + 0x8A;
|
|
private const int LVM_SETCOLUMN = LVM_FIRST + 96;
|
|
private const int LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54;
|
|
private const int LVM_SETGROUPINFO = LVM_FIRST + 147;
|
|
private const int LVM_SETGROUPMETRICS = LVM_FIRST + 155;
|
|
private const int LVM_SETIMAGELIST = LVM_FIRST + 3;
|
|
private const int LVM_SETITEM = LVM_FIRST + 76;
|
|
private const int LVM_SETITEMCOUNT = LVM_FIRST + 47;
|
|
private const int LVM_SETITEMSTATE = LVM_FIRST + 43;
|
|
private const int LVM_SETSELECTEDCOLUMN = LVM_FIRST + 140;
|
|
private const int LVM_SETTOOLTIPS = LVM_FIRST + 74;
|
|
private const int LVM_SUBITEMHITTEST = LVM_FIRST + 57;
|
|
private const int LVS_EX_SUBITEMIMAGES = 0x0002;
|
|
|
|
private const int LVIF_TEXT = 0x0001;
|
|
private const int LVIF_IMAGE = 0x0002;
|
|
private const int LVIF_PARAM = 0x0004;
|
|
private const int LVIF_STATE = 0x0008;
|
|
private const int LVIF_INDENT = 0x0010;
|
|
private const int LVIF_NORECOMPUTE = 0x0800;
|
|
|
|
private const int LVIS_SELECTED = 2;
|
|
|
|
private const int LVCF_FMT = 0x0001;
|
|
private const int LVCF_WIDTH = 0x0002;
|
|
private const int LVCF_TEXT = 0x0004;
|
|
private const int LVCF_SUBITEM = 0x0008;
|
|
private const int LVCF_IMAGE = 0x0010;
|
|
private const int LVCF_ORDER = 0x0020;
|
|
private const int LVCFMT_LEFT = 0x0000;
|
|
private const int LVCFMT_RIGHT = 0x0001;
|
|
private const int LVCFMT_CENTER = 0x0002;
|
|
private const int LVCFMT_JUSTIFYMASK = 0x0003;
|
|
|
|
private const int LVCFMT_IMAGE = 0x0800;
|
|
private const int LVCFMT_BITMAP_ON_RIGHT = 0x1000;
|
|
private const int LVCFMT_COL_HAS_IMAGES = 0x8000;
|
|
|
|
private const int LVBKIF_SOURCE_NONE = 0x0;
|
|
private const int LVBKIF_SOURCE_HBITMAP = 0x1;
|
|
private const int LVBKIF_SOURCE_URL = 0x2;
|
|
private const int LVBKIF_SOURCE_MASK = 0x3;
|
|
private const int LVBKIF_STYLE_NORMAL = 0x0;
|
|
private const int LVBKIF_STYLE_TILE = 0x10;
|
|
private const int LVBKIF_STYLE_MASK = 0x10;
|
|
private const int LVBKIF_FLAG_TILEOFFSET = 0x100;
|
|
private const int LVBKIF_TYPE_WATERMARK = 0x10000000;
|
|
private const int LVBKIF_FLAG_ALPHABLEND = 0x20000000;
|
|
|
|
private const int LVSICF_NOINVALIDATEALL = 1;
|
|
private const int LVSICF_NOSCROLL = 2;
|
|
|
|
private const int HDM_FIRST = 0x1200;
|
|
private const int HDM_HITTEST = HDM_FIRST + 6;
|
|
private const int HDM_GETITEMRECT = HDM_FIRST + 7;
|
|
private const int HDM_GETITEM = HDM_FIRST + 11;
|
|
private const int HDM_SETITEM = HDM_FIRST + 12;
|
|
|
|
private const int HDI_WIDTH = 0x0001;
|
|
private const int HDI_TEXT = 0x0002;
|
|
private const int HDI_FORMAT = 0x0004;
|
|
private const int HDI_BITMAP = 0x0010;
|
|
private const int HDI_IMAGE = 0x0020;
|
|
|
|
private const int HDF_LEFT = 0x0000;
|
|
private const int HDF_RIGHT = 0x0001;
|
|
private const int HDF_CENTER = 0x0002;
|
|
private const int HDF_JUSTIFYMASK = 0x0003;
|
|
private const int HDF_RTLREADING = 0x0004;
|
|
private const int HDF_STRING = 0x4000;
|
|
private const int HDF_BITMAP = 0x2000;
|
|
private const int HDF_BITMAP_ON_RIGHT = 0x1000;
|
|
private const int HDF_IMAGE = 0x0800;
|
|
private const int HDF_SORTUP = 0x0400;
|
|
private const int HDF_SORTDOWN = 0x0200;
|
|
|
|
private const int SB_HORZ = 0;
|
|
private const int SB_VERT = 1;
|
|
private const int SB_CTL = 2;
|
|
private const int SB_BOTH = 3;
|
|
|
|
private const int SIF_RANGE = 0x0001;
|
|
private const int SIF_PAGE = 0x0002;
|
|
private const int SIF_POS = 0x0004;
|
|
private const int SIF_DISABLENOSCROLL = 0x0008;
|
|
private const int SIF_TRACKPOS = 0x0010;
|
|
private const int SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS);
|
|
|
|
private const int ILD_NORMAL = 0x0;
|
|
private const int ILD_TRANSPARENT = 0x1;
|
|
private const int ILD_MASK = 0x10;
|
|
private const int ILD_IMAGE = 0x20;
|
|
private const int ILD_BLEND25 = 0x2;
|
|
private const int ILD_BLEND50 = 0x4;
|
|
|
|
const int SWP_NOSIZE = 1;
|
|
const int SWP_NOMOVE = 2;
|
|
const int SWP_NOZORDER = 4;
|
|
const int SWP_NOREDRAW = 8;
|
|
const int SWP_NOACTIVATE = 16;
|
|
public const int SWP_FRAMECHANGED = 32;
|
|
|
|
const int SWP_ZORDERONLY = SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOACTIVATE;
|
|
const int SWP_SIZEONLY = SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOACTIVATE;
|
|
const int SWP_UPDATE_FRAME = SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED;
|
|
|
|
#endregion
|
|
|
|
#region Structures
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct HDITEM
|
|
{
|
|
public int mask;
|
|
public int cxy;
|
|
public IntPtr pszText;
|
|
public IntPtr hbm;
|
|
public int cchTextMax;
|
|
public int fmt;
|
|
public IntPtr lParam;
|
|
public int iImage;
|
|
public int iOrder;
|
|
//if (_WIN32_IE >= 0x0500)
|
|
public int type;
|
|
public IntPtr pvFilter;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public class HDHITTESTINFO
|
|
{
|
|
public int pt_x;
|
|
public int pt_y;
|
|
public int flags;
|
|
public int iItem;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public class HDLAYOUT
|
|
{
|
|
public IntPtr prc;
|
|
public IntPtr pwpos;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct IMAGELISTDRAWPARAMS
|
|
{
|
|
public int cbSize;
|
|
public IntPtr himl;
|
|
public int i;
|
|
public IntPtr hdcDst;
|
|
public int x;
|
|
public int y;
|
|
public int cx;
|
|
public int cy;
|
|
public int xBitmap;
|
|
public int yBitmap;
|
|
public uint rgbBk;
|
|
public uint rgbFg;
|
|
public uint fStyle;
|
|
public uint dwRop;
|
|
public uint fState;
|
|
public uint Frame;
|
|
public uint crEffect;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
|
public struct LVBKIMAGE
|
|
{
|
|
public int ulFlags;
|
|
public IntPtr hBmp;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszImage;
|
|
public int cchImageMax;
|
|
public int xOffset;
|
|
public int yOffset;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
|
public struct LVCOLUMN
|
|
{
|
|
public int mask;
|
|
public int fmt;
|
|
public int cx;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszText;
|
|
public int cchTextMax;
|
|
public int iSubItem;
|
|
// These are available in Common Controls >= 0x0300
|
|
public int iImage;
|
|
public int iOrder;
|
|
};
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
|
public struct LVFINDINFO
|
|
{
|
|
public int flags;
|
|
public string psz;
|
|
public IntPtr lParam;
|
|
public int ptX;
|
|
public int ptY;
|
|
public int vkDirection;
|
|
}
|
|
|
|
[StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
|
public struct LVGROUP
|
|
{
|
|
public uint cbSize;
|
|
public uint mask;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszHeader;
|
|
public int cchHeader;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszFooter;
|
|
public int cchFooter;
|
|
public int iGroupId;
|
|
public uint stateMask;
|
|
public uint state;
|
|
public uint uAlign;
|
|
}
|
|
|
|
[StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
|
public struct LVGROUP2
|
|
{
|
|
public uint cbSize;
|
|
public uint mask;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszHeader;
|
|
public uint cchHeader;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszFooter;
|
|
public int cchFooter;
|
|
public int iGroupId;
|
|
public uint stateMask;
|
|
public uint state;
|
|
public uint uAlign;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszSubtitle;
|
|
public uint cchSubtitle;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszTask;
|
|
public uint cchTask;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszDescriptionTop;
|
|
public uint cchDescriptionTop;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszDescriptionBottom;
|
|
public uint cchDescriptionBottom;
|
|
public int iTitleImage;
|
|
public int iExtendedImage;
|
|
public int iFirstItem; // Read only
|
|
public int cItems; // Read only
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszSubsetTitle; // NULL if group is not subset
|
|
public uint cchSubsetTitle;
|
|
}
|
|
|
|
[StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
|
public struct LVGROUPMETRICS
|
|
{
|
|
public uint cbSize;
|
|
public uint mask;
|
|
public uint Left;
|
|
public uint Top;
|
|
public uint Right;
|
|
public uint Bottom;
|
|
public int crLeft;
|
|
public int crTop;
|
|
public int crRight;
|
|
public int crBottom;
|
|
public int crHeader;
|
|
public int crFooter;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
|
public struct LVHITTESTINFO
|
|
{
|
|
public int pt_x;
|
|
public int pt_y;
|
|
public int flags;
|
|
public int iItem;
|
|
public int iSubItem;
|
|
public int iGroup;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
|
public struct LVITEM
|
|
{
|
|
public int mask;
|
|
public int iItem;
|
|
public int iSubItem;
|
|
public int state;
|
|
public int stateMask;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string pszText;
|
|
public int cchTextMax;
|
|
public int iImage;
|
|
public IntPtr lParam;
|
|
// These are available in Common Controls >= 0x0300
|
|
public int iIndent;
|
|
// These are available in Common Controls >= 0x056
|
|
public int iGroupId;
|
|
public int cColumns;
|
|
public IntPtr puColumns;
|
|
};
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NMHDR
|
|
{
|
|
public IntPtr hwndFrom;
|
|
public IntPtr idFrom;
|
|
public int code;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NMCUSTOMDRAW
|
|
{
|
|
public NativeMethods.NMHDR nmcd;
|
|
public int dwDrawStage;
|
|
public IntPtr hdc;
|
|
public NativeMethods.RECT rc;
|
|
public IntPtr dwItemSpec;
|
|
public int uItemState;
|
|
public IntPtr lItemlParam;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NMHEADER
|
|
{
|
|
public NMHDR nhdr;
|
|
public int iItem;
|
|
public int iButton;
|
|
public IntPtr pHDITEM;
|
|
}
|
|
|
|
const int MAX_LINKID_TEXT = 48;
|
|
const int L_MAX_URL_LENGTH = 2048 + 32 + 4;
|
|
//#define L_MAX_URL_LENGTH (2048 + 32 + sizeof("://"))
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
public struct LITEM
|
|
{
|
|
public uint mask;
|
|
public int iLink;
|
|
public uint state;
|
|
public uint stateMask;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_LINKID_TEXT)]
|
|
public string szID;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = L_MAX_URL_LENGTH)]
|
|
public string szUrl;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NMLISTVIEW
|
|
{
|
|
public NativeMethods.NMHDR hdr;
|
|
public int iItem;
|
|
public int iSubItem;
|
|
public int uNewState;
|
|
public int uOldState;
|
|
public int uChanged;
|
|
public IntPtr lParam;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NMLVCUSTOMDRAW
|
|
{
|
|
public NativeMethods.NMCUSTOMDRAW nmcd;
|
|
public int clrText;
|
|
public int clrTextBk;
|
|
public int iSubItem;
|
|
public int dwItemType;
|
|
public int clrFace;
|
|
public int iIconEffect;
|
|
public int iIconPhase;
|
|
public int iPartId;
|
|
public int iStateId;
|
|
public NativeMethods.RECT rcText;
|
|
public uint uAlign;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NMLVFINDITEM
|
|
{
|
|
public NativeMethods.NMHDR hdr;
|
|
public int iStart;
|
|
public NativeMethods.LVFINDINFO lvfi;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NMLVGETINFOTIP
|
|
{
|
|
public NativeMethods.NMHDR hdr;
|
|
public int dwFlags;
|
|
public string pszText;
|
|
public int cchTextMax;
|
|
public int iItem;
|
|
public int iSubItem;
|
|
public IntPtr lParam;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NMLVGROUP
|
|
{
|
|
public NMHDR hdr;
|
|
public int iGroupId; // which group is changing
|
|
public uint uNewState; // LVGS_xxx flags
|
|
public uint uOldState;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NMLVLINK
|
|
{
|
|
public NMHDR hdr;
|
|
public LITEM link;
|
|
public int iItem;
|
|
public int iSubItem;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NMLVSCROLL
|
|
{
|
|
public NativeMethods.NMHDR hdr;
|
|
public int dx;
|
|
public int dy;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
|
public struct NMTTDISPINFO
|
|
{
|
|
public NativeMethods.NMHDR hdr;
|
|
[MarshalAs(UnmanagedType.LPTStr)]
|
|
public string lpszText;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
|
|
public string szText;
|
|
public IntPtr hinst;
|
|
public int uFlags;
|
|
public IntPtr lParam;
|
|
//public int hbmp; This is documented but doesn't work
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct RECT
|
|
{
|
|
public int left;
|
|
public int top;
|
|
public int right;
|
|
public int bottom;
|
|
}
|
|
|
|
[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, CharSet = CharSet.Auto)]
|
|
public class TOOLINFO
|
|
{
|
|
public int cbSize = Marshal.SizeOf(typeof(NativeMethods.TOOLINFO));
|
|
public int uFlags;
|
|
public IntPtr hwnd;
|
|
public IntPtr uId;
|
|
public NativeMethods.RECT rect;
|
|
public IntPtr hinst = IntPtr.Zero;
|
|
public IntPtr lpszText;
|
|
public IntPtr lParam = IntPtr.Zero;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct WINDOWPOS
|
|
{
|
|
public IntPtr hwnd;
|
|
public IntPtr hwndInsertAfter;
|
|
public int x;
|
|
public int y;
|
|
public int cx;
|
|
public int cy;
|
|
public int flags;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Entry points
|
|
|
|
// Various flavours of SendMessage: plain vanilla, and passing references to various structures
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, int lParam);
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
|
|
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessageLVItem(IntPtr hWnd, int msg, int wParam, ref LVITEM lvi);
|
|
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref LVHITTESTINFO ht);
|
|
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessageRECT(IntPtr hWnd, int msg, int wParam, ref RECT r);
|
|
//[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
|
|
//private static extern IntPtr SendMessageLVColumn(IntPtr hWnd, int m, int wParam, ref LVCOLUMN lvc);
|
|
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
|
|
private static extern IntPtr SendMessageHDItem(IntPtr hWnd, int msg, int wParam, ref HDITEM hdi);
|
|
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessageHDHITTESTINFO(IntPtr hWnd, int Msg, IntPtr wParam, [In, Out] HDHITTESTINFO lParam);
|
|
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessageTOOLINFO(IntPtr hWnd, int Msg, int wParam, NativeMethods.TOOLINFO lParam);
|
|
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessageLVBKIMAGE(IntPtr hWnd, int Msg, int wParam, ref NativeMethods.LVBKIMAGE lParam);
|
|
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessageString(IntPtr hWnd, int Msg, int wParam, string lParam);
|
|
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessageIUnknown(IntPtr hWnd, int msg, [MarshalAs(UnmanagedType.IUnknown)] object wParam, int lParam);
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref LVGROUP lParam);
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref LVGROUP2 lParam);
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref LVGROUPMETRICS lParam);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
public static extern bool DeleteObject(IntPtr objectHandle);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
|
|
public static extern bool GetClientRect(IntPtr hWnd, ref Rectangle r);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
|
|
public static extern bool GetScrollInfo(IntPtr hWnd, int fnBar, SCROLLINFO scrollInfo);
|
|
|
|
[DllImport("user32.dll", EntryPoint = "GetUpdateRect", CharSet = CharSet.Auto)]
|
|
private static extern bool GetUpdateRectInternal(IntPtr hWnd, ref Rectangle r, bool eraseBackground);
|
|
|
|
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
|
|
private static extern bool ImageList_Draw(IntPtr himl, int i, IntPtr hdcDst, int x, int y, int fStyle);
|
|
|
|
[DllImport("comctl32.dll", CharSet = CharSet.Auto)]
|
|
private static extern bool ImageList_DrawIndirect(ref IMAGELISTDRAWPARAMS parms);
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
public static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle r);
|
|
|
|
[DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
|
|
|
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);
|
|
|
|
[DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SetWindowLongPtr32(IntPtr hWnd, int nIndex, int dwNewLong);
|
|
|
|
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, int dwNewLong);
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
|
|
|
[DllImport("user32.dll", EntryPoint = "ValidateRect", CharSet = CharSet.Auto)]
|
|
private static extern IntPtr ValidatedRectInternal(IntPtr hWnd, ref Rectangle r);
|
|
|
|
#endregion
|
|
|
|
//[DllImport("user32.dll", EntryPoint = "LockWindowUpdate", CharSet = CharSet.Auto)]
|
|
//private static extern int LockWindowUpdateInternal(IntPtr hWnd);
|
|
|
|
//public static void LockWindowUpdate(IWin32Window window) {
|
|
// if (window == null)
|
|
// NativeMethods.LockWindowUpdateInternal(IntPtr.Zero);
|
|
// else
|
|
// NativeMethods.LockWindowUpdateInternal(window.Handle);
|
|
//}
|
|
|
|
/// <summary>
|
|
/// Put an image under the ListView.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// The ListView must have its handle created before calling this.
|
|
/// </para>
|
|
/// <para>
|
|
/// This doesn't work very well. Specifically, it doesn't play well with owner drawn,
|
|
/// and grid lines are drawn over it.
|
|
/// </para>
|
|
/// </remarks>
|
|
/// <param name="lv"></param>
|
|
/// <param name="image">The image to be used as the background. If this is null, any existing background image will be cleared.</param>
|
|
/// <param name="isWatermark">If this is true, the image is pinned to the bottom right and does not scroll. The other parameters are ignored</param>
|
|
/// <param name="isTiled">If this is true, the image will be tiled to fill the whole control background. The offset parameters will be ignored.</param>
|
|
/// <param name="xOffset">If both watermark and tiled are false, this indicates the horizontal percentage where the image will be placed. 0 is absolute left, 100 is absolute right.</param>
|
|
/// <param name="yOffset">If both watermark and tiled are false, this indicates the vertical percentage where the image will be placed.</param>
|
|
/// <returns></returns>
|
|
public static bool SetBackgroundImage(ListView lv, Image image, bool isWatermark, bool isTiled, int xOffset, int yOffset) {
|
|
|
|
LVBKIMAGE lvbkimage = new LVBKIMAGE();
|
|
|
|
// We have to clear any pre-existing background image, otherwise the attempt to set the image will fail.
|
|
// We don't know which type may already have been set, so we just clear both the watermark and the image.
|
|
lvbkimage.ulFlags = LVBKIF_TYPE_WATERMARK;
|
|
IntPtr result = NativeMethods.SendMessageLVBKIMAGE(lv.Handle, LVM_SETBKIMAGE, 0, ref lvbkimage);
|
|
lvbkimage.ulFlags = LVBKIF_SOURCE_HBITMAP;
|
|
result = NativeMethods.SendMessageLVBKIMAGE(lv.Handle, LVM_SETBKIMAGE, 0, ref lvbkimage);
|
|
|
|
Bitmap bm = image as Bitmap;
|
|
if (bm != null) {
|
|
lvbkimage.hBmp = bm.GetHbitmap();
|
|
lvbkimage.ulFlags = isWatermark ? LVBKIF_TYPE_WATERMARK : (isTiled ? LVBKIF_SOURCE_HBITMAP | LVBKIF_STYLE_TILE : LVBKIF_SOURCE_HBITMAP);
|
|
lvbkimage.xOffset = xOffset;
|
|
lvbkimage.yOffset = yOffset;
|
|
result = NativeMethods.SendMessageLVBKIMAGE(lv.Handle, LVM_SETBKIMAGE, 0, ref lvbkimage);
|
|
}
|
|
|
|
return (result != IntPtr.Zero);
|
|
}
|
|
|
|
public static bool DrawImageList(Graphics g, ImageList il, int index, int x, int y, bool isSelected, bool isDisabled) {
|
|
ImageListDrawItemConstants flags = (isSelected ? ImageListDrawItemConstants.ILD_SELECTED : ImageListDrawItemConstants.ILD_NORMAL) | ImageListDrawItemConstants.ILD_TRANSPARENT;
|
|
ImageListDrawStateConstants state = isDisabled ? ImageListDrawStateConstants.ILS_SATURATE : ImageListDrawStateConstants.ILS_NORMAL;
|
|
try {
|
|
IntPtr hdc = g.GetHdc();
|
|
return DrawImage(il, hdc, index, x, y, flags, 0, 0, state);
|
|
}
|
|
finally {
|
|
g.ReleaseHdc();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Flags controlling how the Image List item is
|
|
/// drawn
|
|
/// </summary>
|
|
[Flags]
|
|
public enum ImageListDrawItemConstants
|
|
{
|
|
/// <summary>
|
|
/// Draw item normally.
|
|
/// </summary>
|
|
ILD_NORMAL = 0x0,
|
|
/// <summary>
|
|
/// Draw item transparently.
|
|
/// </summary>
|
|
ILD_TRANSPARENT = 0x1,
|
|
/// <summary>
|
|
/// Draw item blended with 25% of the specified foreground colour
|
|
/// or the Highlight colour if no foreground colour specified.
|
|
/// </summary>
|
|
ILD_BLEND25 = 0x2,
|
|
/// <summary>
|
|
/// Draw item blended with 50% of the specified foreground colour
|
|
/// or the Highlight colour if no foreground colour specified.
|
|
/// </summary>
|
|
ILD_SELECTED = 0x4,
|
|
/// <summary>
|
|
/// Draw the icon's mask
|
|
/// </summary>
|
|
ILD_MASK = 0x10,
|
|
/// <summary>
|
|
/// Draw the icon image without using the mask
|
|
/// </summary>
|
|
ILD_IMAGE = 0x20,
|
|
/// <summary>
|
|
/// Draw the icon using the ROP specified.
|
|
/// </summary>
|
|
ILD_ROP = 0x40,
|
|
/// <summary>
|
|
/// Preserves the alpha channel in dest. XP only.
|
|
/// </summary>
|
|
ILD_PRESERVEALPHA = 0x1000,
|
|
/// <summary>
|
|
/// Scale the image to cx, cy instead of clipping it. XP only.
|
|
/// </summary>
|
|
ILD_SCALE = 0x2000,
|
|
/// <summary>
|
|
/// Scale the image to the current DPI of the display. XP only.
|
|
/// </summary>
|
|
ILD_DPISCALE = 0x4000
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enumeration containing XP ImageList Draw State options
|
|
/// </summary>
|
|
[Flags]
|
|
public enum ImageListDrawStateConstants
|
|
{
|
|
/// <summary>
|
|
/// The image state is not modified.
|
|
/// </summary>
|
|
ILS_NORMAL = (0x00000000),
|
|
/// <summary>
|
|
/// Adds a glow effect to the icon, which causes the icon to appear to glow
|
|
/// with a given color around the edges. (Note: does not appear to be implemented)
|
|
/// </summary>
|
|
ILS_GLOW = (0x00000001), //The color for the glow effect is passed to the IImageList::Draw method in the crEffect member of IMAGELISTDRAWPARAMS.
|
|
/// <summary>
|
|
/// Adds a drop shadow effect to the icon. (Note: does not appear to be implemented)
|
|
/// </summary>
|
|
ILS_SHADOW = (0x00000002), //The color for the drop shadow effect is passed to the IImageList::Draw method in the crEffect member of IMAGELISTDRAWPARAMS.
|
|
/// <summary>
|
|
/// Saturates the icon by increasing each color component
|
|
/// of the RGB triplet for each pixel in the icon. (Note: only ever appears to result in a completely unsaturated icon)
|
|
/// </summary>
|
|
ILS_SATURATE = (0x00000004), // The amount to increase is indicated by the frame member in the IMAGELISTDRAWPARAMS method.
|
|
/// <summary>
|
|
/// Alpha blends the icon. Alpha blending controls the transparency
|
|
/// level of an icon, according to the value of its alpha channel.
|
|
/// (Note: does not appear to be implemented).
|
|
/// </summary>
|
|
ILS_ALPHA = (0x00000008) //The value of the alpha channel is indicated by the frame member in the IMAGELISTDRAWPARAMS method. The alpha channel can be from 0 to 255, with 0 being completely transparent, and 255 being completely opaque.
|
|
}
|
|
|
|
private const uint CLR_DEFAULT = 0xFF000000;
|
|
|
|
/// <summary>
|
|
/// Draws an image using the specified flags and state on XP systems.
|
|
/// </summary>
|
|
/// <param name="il">The image list from which an item will be drawn</param>
|
|
/// <param name="hdc">Device context to draw to</param>
|
|
/// <param name="index">Index of image to draw</param>
|
|
/// <param name="x">X Position to draw at</param>
|
|
/// <param name="y">Y Position to draw at</param>
|
|
/// <param name="flags">Drawing flags</param>
|
|
/// <param name="cx">Width to draw</param>
|
|
/// <param name="cy">Height to draw</param>
|
|
/// <param name="stateFlags">State flags</param>
|
|
public static bool DrawImage(ImageList il, IntPtr hdc, int index, int x, int y, ImageListDrawItemConstants flags, int cx, int cy, ImageListDrawStateConstants stateFlags) {
|
|
IMAGELISTDRAWPARAMS pimldp = new IMAGELISTDRAWPARAMS();
|
|
pimldp.hdcDst = hdc;
|
|
pimldp.cbSize = Marshal.SizeOf(pimldp.GetType());
|
|
pimldp.i = index;
|
|
pimldp.x = x;
|
|
pimldp.y = y;
|
|
pimldp.cx = cx;
|
|
pimldp.cy = cy;
|
|
pimldp.rgbFg = CLR_DEFAULT;
|
|
pimldp.fStyle = (uint) flags;
|
|
pimldp.fState = (uint) stateFlags;
|
|
pimldp.himl = il.Handle;
|
|
return ImageList_DrawIndirect(ref pimldp);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Make sure the ListView has the extended style that says to display subitem images.
|
|
/// </summary>
|
|
/// <remarks>This method must be called after any .NET call that update the extended styles
|
|
/// since they seem to erase this setting.</remarks>
|
|
/// <param name="list">The listview to send a m to</param>
|
|
public static void ForceSubItemImagesExStyle(ListView list) {
|
|
SendMessage(list.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_SUBITEMIMAGES, LVS_EX_SUBITEMIMAGES);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Change the virtual list size of the given ListView (which must be in virtual mode)
|
|
/// </summary>
|
|
/// <remarks>This will not change the scroll position</remarks>
|
|
/// <param name="list">The listview to send a message to</param>
|
|
/// <param name="count">How many rows should the list have?</param>
|
|
public static void SetItemCount(ListView list, int count) {
|
|
SendMessage(list.Handle, LVM_SETITEMCOUNT, count, LVSICF_NOSCROLL);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Make sure the ListView has the extended style that says to display subitem images.
|
|
/// </summary>
|
|
/// <remarks>This method must be called after any .NET call that update the extended styles
|
|
/// since they seem to erase this setting.</remarks>
|
|
/// <param name="list">The listview to send a m to</param>
|
|
/// <param name="style"></param>
|
|
/// <param name="styleMask"></param>
|
|
public static void SetExtendedStyle(ListView list, int style, int styleMask) {
|
|
SendMessage(list.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, styleMask, style);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculates the number of items that can fit vertically in the visible area of a list-view (which
|
|
/// must be in details or list view.
|
|
/// </summary>
|
|
/// <param name="list">The listView</param>
|
|
/// <returns>Number of visible items per page</returns>
|
|
public static int GetCountPerPage(ListView list) {
|
|
return (int)SendMessage(list.Handle, LVM_GETCOUNTPERPAGE, 0, 0);
|
|
}
|
|
/// <summary>
|
|
/// For the given item and subitem, make it display the given image
|
|
/// </summary>
|
|
/// <param name="list">The listview to send a m to</param>
|
|
/// <param name="itemIndex">row number (0 based)</param>
|
|
/// <param name="subItemIndex">subitem (0 is the item itself)</param>
|
|
/// <param name="imageIndex">index into the image list</param>
|
|
public static void SetSubItemImage(ListView list, int itemIndex, int subItemIndex, int imageIndex) {
|
|
LVITEM lvItem = new LVITEM();
|
|
lvItem.mask = LVIF_IMAGE;
|
|
lvItem.iItem = itemIndex;
|
|
lvItem.iSubItem = subItemIndex;
|
|
lvItem.iImage = imageIndex;
|
|
SendMessageLVItem(list.Handle, LVM_SETITEM, 0, ref lvItem);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Setup the given column of the listview to show the given image to the right of the text.
|
|
/// If the image index is -1, any previous image is cleared
|
|
/// </summary>
|
|
/// <param name="list">The listview to send a m to</param>
|
|
/// <param name="columnIndex">Index of the column to modifiy</param>
|
|
/// <param name="order"></param>
|
|
/// <param name="imageIndex">Index into the small image list</param>
|
|
public static void SetColumnImage(ListView list, int columnIndex, SortOrder order, int imageIndex) {
|
|
IntPtr hdrCntl = NativeMethods.GetHeaderControl(list);
|
|
if (hdrCntl.ToInt32() == 0)
|
|
return;
|
|
|
|
HDITEM item = new HDITEM();
|
|
item.mask = HDI_FORMAT;
|
|
IntPtr result = SendMessageHDItem(hdrCntl, HDM_GETITEM, columnIndex, ref item);
|
|
|
|
item.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN | HDF_IMAGE | HDF_BITMAP_ON_RIGHT);
|
|
|
|
if (NativeMethods.HasBuiltinSortIndicators()) {
|
|
if (order == SortOrder.Ascending)
|
|
item.fmt |= HDF_SORTUP;
|
|
if (order == SortOrder.Descending)
|
|
item.fmt |= HDF_SORTDOWN;
|
|
} else {
|
|
item.mask |= HDI_IMAGE;
|
|
item.fmt |= (HDF_IMAGE | HDF_BITMAP_ON_RIGHT);
|
|
item.iImage = imageIndex;
|
|
}
|
|
|
|
result = SendMessageHDItem(hdrCntl, HDM_SETITEM, columnIndex, ref item);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Does this version of the operating system have builtin sort indicators?
|
|
/// </summary>
|
|
/// <returns>Are there builtin sort indicators</returns>
|
|
/// <remarks>XP and later have these</remarks>
|
|
public static bool HasBuiltinSortIndicators() {
|
|
return OSFeature.Feature.GetVersionPresent(OSFeature.Themes) != null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return the bounds of the update region on the given control.
|
|
/// </summary>
|
|
/// <remarks>The BeginPaint() system call validates the update region, effectively wiping out this information.
|
|
/// So this call has to be made before the BeginPaint() call.</remarks>
|
|
/// <param name="cntl">The control whose update region is be calculated</param>
|
|
/// <returns>A rectangle</returns>
|
|
public static Rectangle GetUpdateRect(Control cntl) {
|
|
Rectangle r = new Rectangle();
|
|
GetUpdateRectInternal(cntl.Handle, ref r, false);
|
|
return r;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate an area of the given control. A validated area will not be repainted at the next redraw.
|
|
/// </summary>
|
|
/// <param name="cntl">The control to be validated</param>
|
|
/// <param name="r">The area of the control to be validated</param>
|
|
public static void ValidateRect(Control cntl, Rectangle r) {
|
|
ValidatedRectInternal(cntl.Handle, ref r);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Select all rows on the given listview
|
|
/// </summary>
|
|
/// <param name="list">The listview whose items are to be selected</param>
|
|
public static void SelectAllItems(ListView list) {
|
|
NativeMethods.SetItemState(list, -1, LVIS_SELECTED, LVIS_SELECTED);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deselect all rows on the given listview
|
|
/// </summary>
|
|
/// <param name="list">The listview whose items are to be deselected</param>
|
|
public static void DeselectAllItems(ListView list) {
|
|
NativeMethods.SetItemState(list, -1, LVIS_SELECTED, 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deselect a single row
|
|
/// </summary>
|
|
/// <param name="list"></param>
|
|
/// <param name="index"></param>
|
|
public static void DeselectOneItem(ListView list, int index) {
|
|
NativeMethods.SetItemState(list, index, LVIS_SELECTED, 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the item state on the given item
|
|
/// </summary>
|
|
/// <param name="list">The listview whose item's state is to be changed</param>
|
|
/// <param name="itemIndex">The index of the item to be changed</param>
|
|
/// <param name="mask">Which bits of the value are to be set?</param>
|
|
/// <param name="value">The value to be set</param>
|
|
public static void SetItemState(ListView list, int itemIndex, int mask, int value) {
|
|
LVITEM lvItem = new LVITEM();
|
|
lvItem.stateMask = mask;
|
|
lvItem.state = value;
|
|
SendMessageLVItem(list.Handle, LVM_SETITEMSTATE, itemIndex, ref lvItem);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scroll the given listview by the given deltas
|
|
/// </summary>
|
|
/// <param name="list"></param>
|
|
/// <param name="dx"></param>
|
|
/// <param name="dy"></param>
|
|
/// <returns>true if the scroll succeeded</returns>
|
|
public static bool Scroll(ListView list, int dx, int dy) {
|
|
return SendMessage(list.Handle, LVM_SCROLL, dx, dy) != IntPtr.Zero;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return the handle to the header control on the given list
|
|
/// </summary>
|
|
/// <param name="list">The listview whose header control is to be returned</param>
|
|
/// <returns>The handle to the header control</returns>
|
|
public static IntPtr GetHeaderControl(ListView list) {
|
|
return SendMessage(list.Handle, LVM_GETHEADER, 0, 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return the edges of the given column.
|
|
/// </summary>
|
|
/// <param name="lv"></param>
|
|
/// <param name="columnIndex"></param>
|
|
/// <returns>A Point holding the left and right co-ords of the column.
|
|
/// -1 means that the sides could not be retrieved.</returns>
|
|
public static Point GetColumnSides(ObjectListView lv, int columnIndex) {
|
|
Point sides = new Point(-1, -1);
|
|
IntPtr hdr = NativeMethods.GetHeaderControl(lv);
|
|
if (hdr == IntPtr.Zero)
|
|
return new Point(-1, -1);
|
|
|
|
RECT r = new RECT();
|
|
NativeMethods.SendMessageRECT(hdr, HDM_GETITEMRECT, columnIndex, ref r);
|
|
return new Point(r.left, r.right);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return the edges of the given column.
|
|
/// </summary>
|
|
/// <param name="lv"></param>
|
|
/// <param name="columnIndex"></param>
|
|
/// <returns>A Point holding the left and right co-ords of the column.
|
|
/// -1 means that the sides could not be retrieved.</returns>
|
|
public static Point GetScrolledColumnSides(ListView lv, int columnIndex) {
|
|
IntPtr hdr = NativeMethods.GetHeaderControl(lv);
|
|
if (hdr == IntPtr.Zero)
|
|
return new Point(-1, -1);
|
|
|
|
RECT r = new RECT();
|
|
IntPtr result = NativeMethods.SendMessageRECT(hdr, HDM_GETITEMRECT, columnIndex, ref r);
|
|
int scrollH = NativeMethods.GetScrollPosition(lv, true);
|
|
return new Point(r.left - scrollH, r.right - scrollH);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return the index of the column of the header that is under the given point.
|
|
/// Return -1 if no column is under the pt
|
|
/// </summary>
|
|
/// <param name="handle">The list we are interested in</param>
|
|
/// <param name="pt">The client co-ords</param>
|
|
/// <returns>The index of the column under the point, or -1 if no column header is under that point</returns>
|
|
public static int GetColumnUnderPoint(IntPtr handle, Point pt) {
|
|
const int HHT_ONHEADER = 2;
|
|
const int HHT_ONDIVIDER = 4;
|
|
return NativeMethods.HeaderControlHitTest(handle, pt, HHT_ONHEADER | HHT_ONDIVIDER);
|
|
}
|
|
|
|
private static int HeaderControlHitTest(IntPtr handle, Point pt, int flag) {
|
|
HDHITTESTINFO testInfo = new HDHITTESTINFO();
|
|
testInfo.pt_x = pt.X;
|
|
testInfo.pt_y = pt.Y;
|
|
IntPtr result = NativeMethods.SendMessageHDHITTESTINFO(handle, HDM_HITTEST, IntPtr.Zero, testInfo);
|
|
if ((testInfo.flags & flag) != 0)
|
|
return testInfo.iItem;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return the index of the divider under the given point. Return -1 if no divider is under the pt
|
|
/// </summary>
|
|
/// <param name="handle">The list we are interested in</param>
|
|
/// <param name="pt">The client co-ords</param>
|
|
/// <returns>The index of the divider under the point, or -1 if no divider is under that point</returns>
|
|
public static int GetDividerUnderPoint(IntPtr handle, Point pt) {
|
|
const int HHT_ONDIVIDER = 4;
|
|
return NativeMethods.HeaderControlHitTest(handle, pt, HHT_ONDIVIDER);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the scroll position of the given scroll bar
|
|
/// </summary>
|
|
/// <param name="lv"></param>
|
|
/// <param name="horizontalBar"></param>
|
|
/// <returns></returns>
|
|
public static int GetScrollPosition(ListView lv, bool horizontalBar) {
|
|
int fnBar = (horizontalBar ? SB_HORZ : SB_VERT);
|
|
|
|
SCROLLINFO scrollInfo = new SCROLLINFO();
|
|
scrollInfo.fMask = SIF_POS;
|
|
if (GetScrollInfo(lv.Handle, fnBar, scrollInfo))
|
|
return scrollInfo.nPos;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Change the z-order to the window 'toBeMoved' so it appear directly on top of 'reference'
|
|
/// </summary>
|
|
/// <param name="toBeMoved"></param>
|
|
/// <param name="reference"></param>
|
|
/// <returns></returns>
|
|
public static bool ChangeZOrder(IWin32Window toBeMoved, IWin32Window reference) {
|
|
return NativeMethods.SetWindowPos(toBeMoved.Handle, reference.Handle, 0, 0, 0, 0, SWP_ZORDERONLY);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Make the given control/window a topmost window
|
|
/// </summary>
|
|
/// <param name="toBeMoved"></param>
|
|
/// <returns></returns>
|
|
public static bool MakeTopMost(IWin32Window toBeMoved) {
|
|
IntPtr HWND_TOPMOST = (IntPtr)(-1);
|
|
return NativeMethods.SetWindowPos(toBeMoved.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_ZORDERONLY);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Change the size of the window without affecting any other attributes
|
|
/// </summary>
|
|
/// <param name="toBeMoved"></param>
|
|
/// <param name="width"></param>
|
|
/// <param name="height"></param>
|
|
/// <returns></returns>
|
|
public static bool ChangeSize(IWin32Window toBeMoved, int width, int height) {
|
|
return NativeMethods.SetWindowPos(toBeMoved.Handle, IntPtr.Zero, 0, 0, width, height, SWP_SIZEONLY);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Show the given window without activating it
|
|
/// </summary>
|
|
/// <param name="win">The window to show</param>
|
|
static public void ShowWithoutActivate(IWin32Window win) {
|
|
const int SW_SHOWNA = 8;
|
|
NativeMethods.ShowWindow(win.Handle, SW_SHOWNA);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Mark the given column as being selected.
|
|
/// </summary>
|
|
/// <param name="objectListView"></param>
|
|
/// <param name="value">The OLVColumn or null to clear</param>
|
|
/// <remarks>
|
|
/// This method works, but it prevents subitems in the given column from having
|
|
/// back colors.
|
|
/// </remarks>
|
|
static public void SetSelectedColumn(ListView objectListView, ColumnHeader value) {
|
|
NativeMethods.SendMessage(objectListView.Handle,
|
|
LVM_SETSELECTEDCOLUMN, (value == null) ? -1 : value.Index, 0);
|
|
}
|
|
|
|
static public int GetTopIndex(ListView lv) {
|
|
return (int)SendMessage(lv.Handle, LVM_GETTOPINDEX, 0, 0);
|
|
}
|
|
|
|
static public IntPtr GetTooltipControl(ListView lv) {
|
|
return SendMessage(lv.Handle, LVM_GETTOOLTIPS, 0, 0);
|
|
}
|
|
|
|
static public IntPtr SetTooltipControl(ListView lv, ToolTipControl tooltip) {
|
|
return SendMessage(lv.Handle, LVM_SETTOOLTIPS, 0, tooltip.Handle);
|
|
}
|
|
|
|
static public bool HasHorizontalScrollBar(ListView lv) {
|
|
const int GWL_STYLE = -16;
|
|
const int WS_HSCROLL = 0x00100000;
|
|
|
|
return (NativeMethods.GetWindowLong(lv.Handle, GWL_STYLE) & WS_HSCROLL) != 0;
|
|
}
|
|
|
|
public static int GetWindowLong(IntPtr hWnd, int nIndex) {
|
|
if (IntPtr.Size == 4)
|
|
return (int)GetWindowLong32(hWnd, nIndex);
|
|
else
|
|
return (int)(long)GetWindowLongPtr64(hWnd, nIndex);
|
|
}
|
|
|
|
public static int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong) {
|
|
if (IntPtr.Size == 4)
|
|
return (int)SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
|
|
else
|
|
return (int)(long)SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
|
|
}
|
|
|
|
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
|
|
public static extern IntPtr SetBkColor(IntPtr hDC, int clr);
|
|
|
|
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
|
|
public static extern IntPtr SetTextColor(IntPtr hDC, int crColor);
|
|
|
|
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
|
|
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr obj);
|
|
|
|
[DllImport("uxtheme.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
|
|
public static extern IntPtr SetWindowTheme(IntPtr hWnd, string subApp, string subIdList);
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
|
|
public static extern bool InvalidateRect(IntPtr hWnd, int ignored, bool erase);
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct LVITEMINDEX
|
|
{
|
|
public int iItem;
|
|
public int iGroup;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct POINT
|
|
{
|
|
public int x;
|
|
public int y;
|
|
}
|
|
|
|
public static int GetGroupInfo(ObjectListView olv, int groupId, ref LVGROUP2 group) {
|
|
return (int)NativeMethods.SendMessage(olv.Handle, LVM_GETGROUPINFO, groupId, ref group);
|
|
}
|
|
|
|
public static GroupState GetGroupState(ObjectListView olv, int groupId, GroupState mask) {
|
|
return (GroupState)NativeMethods.SendMessage(olv.Handle, LVM_GETGROUPSTATE, groupId, (int)mask);
|
|
}
|
|
|
|
public static int InsertGroup(ObjectListView olv, LVGROUP2 group) {
|
|
return (int)NativeMethods.SendMessage(olv.Handle, LVM_INSERTGROUP, -1, ref group);
|
|
}
|
|
|
|
public static int SetGroupInfo(ObjectListView olv, int groupId, LVGROUP2 group) {
|
|
return (int)NativeMethods.SendMessage(olv.Handle, LVM_SETGROUPINFO, groupId, ref group);
|
|
}
|
|
|
|
public static int SetGroupMetrics(ObjectListView olv, LVGROUPMETRICS metrics) {
|
|
return (int)NativeMethods.SendMessage(olv.Handle, LVM_SETGROUPMETRICS, 0, ref metrics);
|
|
}
|
|
|
|
public static void ClearGroups(VirtualObjectListView virtualObjectListView) {
|
|
NativeMethods.SendMessage(virtualObjectListView.Handle, LVM_REMOVEALLGROUPS, 0, 0);
|
|
}
|
|
|
|
public static void SetGroupImageList(ObjectListView olv, ImageList il) {
|
|
const int LVSIL_GROUPHEADER = 3;
|
|
IntPtr handle = IntPtr.Zero;
|
|
if (il != null)
|
|
handle = il.Handle;
|
|
NativeMethods.SendMessage(olv.Handle, LVM_SETIMAGELIST, LVSIL_GROUPHEADER, handle);
|
|
}
|
|
|
|
public static int HitTest(ObjectListView olv, ref LVHITTESTINFO hittest)
|
|
{
|
|
return (int)NativeMethods.SendMessage(olv.Handle, olv.View == View.Details ? LVM_SUBITEMHITTEST : LVM_HITTEST, -1, ref hittest);
|
|
}
|
|
}
|
|
}
|