PC Review Forums Newsgroups Microsoft DotNet Microsoft Dot NET Framework Forms Can't properly handle NM_CUSTOMDRAW in listview

Reply

Can't properly handle NM_CUSTOMDRAW in listview

 
Thread Tools Rate Thread
Old 14-12-2005, 09:05 PM   #1
=?Utf-8?B?am9obm55IHA=?=
Guest
 
Posts: n/a
Default Can't properly handle NM_CUSTOMDRAW in listview


From my understanding, the C# listview class is a wrapper around the win32
listview and all win32 functionality is available through the wndproc method.
I want to modify the C# listview class (change a row's default height and
text color) and the easiest way do this is through custom drawing (I think).
I know this is possible through onpaint but that may be overkill for what I
want to do. I have overriden the listview wndproc and handled the proper
messages. However, I can't get my changes to show up in the listview. The
listview is in detail view. Is their something special I have to do to
enable custom drawing painting? Is their a win32 style I have to enable? I
am receiving the the custom draw messages in CDDS_ITEMPREPAINT and
CDDS_SUBITEM | CDDS_ITEMPREPAINT but my color and height changes don't show
up i the listview UI. Here is my wndproc. All help is appreciated.

protected override void WndProc(ref Message m)
{
int iRow, iCol;
bool bSelected;
NMHDR nmhdr;
NMLVCUSTOMDRAW nmLvDraw;

switch((uint)m.Msg)
{
case OCM_WM_NOTFY:
case WM_NOTIFY:
nmhdr = (NMHDR) m.GetLParam(typeof(NMHDR));
switch(nmhdr.code)
{
case NM_CUSTOMDRAW:
base.WndProc(ref m);
nmLvDraw = (NMLVCUSTOMDRAW) m.GetLParam(typeof(NMLVCUSTOMDRAW));
switch(nmLvDraw.nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
m.Result = (IntPtr) CDRF_NOTIFYITEMDRAW; break;
case CDDS_ITEMPREPAINT:
//below color and pixel
changes won't take
nmLvDraw.clrText = RGB(255, 0, 0);
nmLvDraw.clrTextBk = RGB(0, 255, 0);
nmLvDraw.nmcd.rc.bottom =
0x20;
// m.Result = (IntPtr) CDRF_NEWFONT;
m.Result = (IntPtr) CDRF_NOTIFYSUBITEMDRAW;
// m.Result = (IntPtr) CDRF_DODEFAULT;
break;

case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
//these changes don't take
either
nmLvDraw.clrText = RGB(255, 0, 0);
nmLvDraw.clrTextBk = RGB(0, 255, 0);
nmLvDraw.nmcd.rc.bottom =
0x20;
m.Result = (IntPtr) CDRF_NEWFONT;
break;
}
return;
}
break;
}
base.WndProc(ref m);
}



  Reply With Quote
Old 14-12-2005, 09:49 PM   #2
Mattias Sjögren
Guest
 
Posts: n/a
Default Re: Can't properly handle NM_CUSTOMDRAW in listview


>However, I can't get my changes to show up in the listview.


Right now you're just modifying your local copy of the NMLVCUSTOMDRAW
struct. You have to copy the changes back to where lParam points with
Marshal.StructureToPtr().


Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
  Reply With Quote
Old 14-12-2005, 10:10 PM   #3
Mick Doherty
Guest
 
Posts: n/a
Default Re: Can't properly handle NM_CUSTOMDRAW in listview

Call base.Wndproc() before modifying the message, not after.

I don't know what you're RGB() method is doing, but it should be returning
something like:
ColorTranslator.ToWin32(Color.Red);

Don't forget to Marshal your modified structure back into m.LParam:
Marshal.StructureToPtr(nmLvDraw, m.LParam, true);

Also you should be looking for the message (WM_REFLECT | WM_NOTIFY) instead
of WM_NOTIFY

I didn't test your code as I'm a bit short on time at the moment, but I
believe it will work with these modifications.

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html


"johnny p" <johnnyp@discussions.microsoft.com> wrote in message
news:A1782321-DC3F-45E8-9F63-8F64F135932B@microsoft.com...
> From my understanding, the C# listview class is a wrapper around the win32
> listview and all win32 functionality is available through the wndproc
> method.
> I want to modify the C# listview class (change a row's default height and
> text color) and the easiest way do this is through custom drawing (I
> think).
> I know this is possible through onpaint but that may be overkill for what
> I
> want to do. I have overriden the listview wndproc and handled the proper
> messages. However, I can't get my changes to show up in the listview.
> The
> listview is in detail view. Is their something special I have to do to
> enable custom drawing painting? Is their a win32 style I have to enable?
> I
> am receiving the the custom draw messages in CDDS_ITEMPREPAINT and
> CDDS_SUBITEM | CDDS_ITEMPREPAINT but my color and height changes don't
> show
> up i the listview UI. Here is my wndproc. All help is appreciated.
>
> protected override void WndProc(ref Message m)
> {
> int iRow, iCol;
> bool bSelected;
> NMHDR nmhdr;
> NMLVCUSTOMDRAW nmLvDraw;
>
> switch((uint)m.Msg)
> {
> case OCM_WM_NOTFY:
> case WM_NOTIFY:
> nmhdr = (NMHDR) m.GetLParam(typeof(NMHDR));
> switch(nmhdr.code)
> {
> case NM_CUSTOMDRAW:
> base.WndProc(ref m);
> nmLvDraw = (NMLVCUSTOMDRAW) m.GetLParam(typeof(NMLVCUSTOMDRAW));
> switch(nmLvDraw.nmcd.dwDrawStage)
> {
> case CDDS_PREPAINT:
> m.Result = (IntPtr) CDRF_NOTIFYITEMDRAW; break;
> case CDDS_ITEMPREPAINT:
> //below color and pixel
> changes won't take
> nmLvDraw.clrText = RGB(255, 0, 0);
> nmLvDraw.clrTextBk = RGB(0, 255, 0);
> nmLvDraw.nmcd.rc.bottom =
> 0x20;
> // m.Result = (IntPtr) CDRF_NEWFONT;
> m.Result = (IntPtr)
> CDRF_NOTIFYSUBITEMDRAW;
> // m.Result = (IntPtr) CDRF_DODEFAULT;
> break;
>
> case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
> //these changes don't take
> either
> nmLvDraw.clrText = RGB(255, 0, 0);
> nmLvDraw.clrTextBk = RGB(0, 255, 0);
> nmLvDraw.nmcd.rc.bottom =
> 0x20;
> m.Result = (IntPtr) CDRF_NEWFONT;
> break;
> }
> return;
> }
> break;
> }
> base.WndProc(ref m);
> }
>
>
>



  Reply With Quote
Old 15-12-2005, 03:45 PM   #4
=?Utf-8?B?am9obm55IHA=?=
Guest
 
Posts: n/a
Default Re: Can't properly handle NM_CUSTOMDRAW in listview


Oops, I knew it was something simple...adding Marshal.StructureToPtr did the
job. However I am still unable to change the listview row height in the
CDDS_ITEMPREPAINT case. I am successfully able to change the colors of the
individual listview subitems in the CDDS_SUBITEM | CDDS_ITEMPREPAINT case.
I know the CDDS_ITEMPREPAINT case handles listview rows so I should be able
to modify the listview row height by changing nmLvDraw.nmcd.rc.bottom, right?
Is their another way to change the row height beside this approach using
custom draw?



  Reply With Quote
Old 17-12-2005, 07:41 PM   #5
Christian ASTOR
Guest
 
Posts: n/a
Default Re: Can't properly handle NM_CUSTOMDRAW in listview

johnny p wrote:

> I know the CDDS_ITEMPREPAINT case handles listview rows so I should be able
> to modify the listview row height by changing nmLvDraw.nmcd.rc.bottom, right?
> Is their another way to change the row height beside this approach using
> custom draw?


No.
The 2 ways to change the items height of a ListView are by
LVS_OWNERDRAWFIXED style or by changing the font with WM_SETFONT
  Reply With Quote
Reply



Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off