Hello,
This is my second question while dealing with custom ListView. I'm wondering how to draw in non column area ?

Hello,
This is my second question while dealing with custom ListView. I'm wondering how to draw in non column area ?

@Arsium-4135
Could you please show the code you have so that we can move on based on yours?
You can draw in WM_ERASEBKGND
But I tested with Custom Draw, not Owner Draw :

After some tests, WM_ERASEBKGND works in C++, but not in C#
But WM_PAINT works :
I added in your ListView class you posted in another thread :
private int WindowSubClass(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam, IntPtr uIdSubclass, uint dwRefData)
{
switch (uMsg)
{
case WM_PAINT:
{
DefSubclassProc(hWnd, uMsg, wParam, lParam);
IntPtr hDC = GetDC(hWnd);
RECT rect = new RECT();
GetClientRect(hWnd, out rect);
int nItemCount = SendMessage(hWnd, HDM_GETITEMCOUNT, 0, IntPtr.Zero);
int nWidth = 0;
for (int i = 0; i < nItemCount; i++)
{
RECT itemRect = new RECT();
SendMessage(hWnd, HDM_GETITEMRECT, i, ref itemRect);
nWidth += (itemRect.right - itemRect.left);
}
using (Graphics g = Graphics.FromHdc(hDC))
{
System.Drawing.Rectangle rectRight = new System.Drawing.Rectangle(nWidth, rect.top, rect.right, rect.bottom);
g.FillRectangle(new SolidBrush(Color.Orange), rectRight);
}
ReleaseDC(hWnd, hDC);
return 0;
}
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
public const int WM_PAINT = 0x000F;
public const int LVM_FIRST = 0x1000;
public const int LVM_GETHEADER = (LVM_FIRST + 31);
public const int HDM_FIRST = 0x1200;
public const int HDM_GETITEMCOUNT = (HDM_FIRST + 0);
public const int HDM_GETITEMRECT = (HDM_FIRST + 7);
[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, uint msg, int wParam, IntPtr lParam);
[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, uint msg, int wParam, ref RECT lParam);
[DllImport("User32.dll", SetLastError = true)]
public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
[DllImport("User32", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("User32", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int Left, int Top, int Right, int Bottom)
{
left = Left;
top = Top;
right = Right;
bottom = Bottom;
}
}
public delegate int SUBCLASSPROC(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam, IntPtr uIdSubclass, uint dwRefData);
[DllImport("Comctl32.dll", SetLastError = true)]
public static extern bool SetWindowSubclass(IntPtr hWnd, SUBCLASSPROC pfnSubclass, uint uIdSubclass, uint dwRefData);
[DllImport("Comctl32.dll", SetLastError = true)]
public static extern int DefSubclassProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
private SUBCLASSPROC SubClassDelegate = null;
private IntPtr hWndHeader = IntPtr.Zero;
protected override void OnCreateControl()
{
hWndHeader = (IntPtr)SendMessage(this.Handle, LVM_GETHEADER, 0, IntPtr.Zero);
SubClassDelegate = WindowSubClass;
if (SubClassDelegate != null)
SetWindowSubclass(hWndHeader, SubClassDelegate, 0, 0);
}
I just subclass the Header control to draw after its Paint event
I used a C++ way, but could be done with a class inherited from NativeWindow
I assumed the Header is displayed from left to right, which can be different (right to left or vertical) and the calculation of the rectangle for FillRectangle should change...
Thx for explanation !
Also this :
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
}
is dead since we handle WM_Paint directly from WM !
8 people are following this question.
Insert a node as child ,before or after a node in nested dynamic JSON Node using C#
Visual Studio 2019: Undefined behavior in a C++/CLI wrapper project.
Example for how to get Package Metadata from Azure DevOps Rest-Api Artifacts using c#
How to collapse individual nested grids/stackpanels inside a grid?