I'm modifying some code I found for drawing the ascending/ descending arrows
on a listview control from a C# project I found on www.codeguru.com.
The C# call to the SendMessage() API and the VB .NET call are giving me
different behaviors.
Here is the SendMessage() declaration in each of them:
VB .NET:
Declare Auto Function SendMessage Lib "User32" (ByVal hWnd As IntPtr, ByRef
msg As RR.Win32.HDM, ByVal wParam As Integer, ByRef hdItem As
RR.Win32.HDITEM) As Integer
C# // RR.Win32 namespace
/// from '.\PlatformSDK\Include\CommCtrl.h'
/// </summary>
public enum Base : int
{
LVM = 0x1000,
TV = 0x1100,
HDM = 0x1200,
TCM = 0x1300,
PGM = 0x1400,
ECM = 0x1500,
BCM = 0x1600,
CBM = 0x1700,
CCM = 0x2000,
NM = 0x0000,
LVN = NM - 100,
HDN = NM - 300,
EM = 0x400,
}
/// <summary>
/// from '.\PlatformSDK\Include\CommCtrl.h'
/// </summary>
public enum HDM : int
{
FIRST = Base.HDM,
GETITEMCOUNT = FIRST + 0,
INSERTITEMA = FIRST + 1,
DELETEITEM = FIRST + 2,
GETITEMA = FIRST + 3,
SETITEMA = FIRST + 4,
LAYOUT = FIRST + 5,
HITTEST = FIRST + 6,
GETITEMRECT = FIRST + 7,
SETIMAGELIST = FIRST + 8,
GETIMAGELIST = FIRST + 9,
INSERTITEMW = FIRST + 10,
GETITEMW = FIRST + 11,
SETITEMW = FIRST + 12,
ORDERTOINDEX = FIRST + 15,
CREATEDRAGIMAGE = FIRST + 16,
GETORDERARRAY = FIRST + 17,
SETORDERARRAY = FIRST + 18,
SETHOTDIVIDER = FIRST + 19,
SETBITMAPMARGIN = FIRST + 20,
GETBITMAPMARGIN = FIRST + 21,
SETFILTERCHANGETIMEOUT = FIRST + 22,
EDITFILTER = FIRST + 23,
CLEARFILTER = FIRST + 24,
}
/// <summary>
/// from '.\PlatformSDK\Include\CommCtrl.h'
/// </summary>
public enum HDF : int
{
LEFT = 0x0000,
RIGHT = 0x0001,
CENTER = 0x0002,
JUSTIFYMASK = 0x0003,
NOJUSTIFY = 0xFFFC,
RTLREADING = 0x0004,
SORTDOWN = 0x0200,
SORTUP = 0x0400,
SORTED = 0x0600,
NOSORT = 0xF1FF,
IMAGE = 0x0800,
BITMAP_ON_RIGHT = 0x1000,
BITMAP = 0x2000,
STRING = 0x4000,
OWNERDRAW = 0x8000
}
/// <summary>
/// from '.\PlatformSDK\Include\CommCtrl.h'
/// </summary>
public enum HDI : int
{
WIDTH = 0x0001,
HEIGHT = WIDTH,
TEXT = 0x0002,
FORMAT = 0x0004,
LPARAM = 0x0008,
BITMAP = 0x0010,
IMAGE = 0x0020,
DI_SETITEM = 0x0040,
ORDER = 0x0080,
FILTER = 0x0100
}
[StructLayout(LayoutKind.Sequential)]
public struct HDITEM
{
public HDI mask;
public int cxy;
public String pszText;
public IntPtr hbm;
public int cchTextMax;
public HDF fmt;
public int lParam;
public int iImage;
public int iOrder;
public uint type;
public IntPtr pvFilter;
}
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, HDM msg, int wParam, ref
HDITEM hditem);
The weirdness is that after I explicitly set the column header glyph to
ascending, and it draws correctly. However, when I try to retrieve the
current format of the glyph using the VB .NET call and GETITEMW, the HDITEM
structure is not being populated.
If I make the same call with the same parameters to the C# version of the
function, the HDITEM structure is getting populated.
I've tested this by placing the C# call in a separate dll in my solution. I
call the VB function first, then call the C# function with the same
arguments. The VB .NET function does not populate the structure; the C#
function does.
Here is the code:
' VB .NET version of function call defined as above: GETITEMW has a value of
4619, column = 0, h = HDITEM structure
Win32.User32.SendMessage(header, RR.Win32.HDM.GETITEMW, column, h) ' does
not populate HDITEM structure with current information: specifically, that
h.fmt = 17408
'C# version of same call defined as above: same parameters as above call.
RR.Win32.User32.SendMessage(header, RR.Win32.HDM.GETITEMW, column, h) 'Does
populate HDITEM structure with current information: specifically that h.fmt
= 17408
There has to be something that I'm missing here. Can anyone help?
Thanks,
Chris
Mattias Sjögren - 10 Nov 2005 18:58 GMT
Chris,
>VB .NET:
>Declare Auto Function SendMessage Lib "User32" (ByVal hWnd As IntPtr, ByRef
>msg As RR.Win32.HDM, ByVal wParam As Integer, ByRef hdItem As
>RR.Win32.HDITEM) As Integer
msg should be passed ByVal.
Mattias

Signature
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Chris McKenzie - 10 Nov 2005 19:17 GMT
Hello,
I made that change as you suggested, but I still get the same behavior.
Thanks for getting back to me so quickly though. :-)
Chris
> Chris,
>
[quoted text clipped - 7 lines]
>
> Mattias
Mattias Sjögren - 10 Nov 2005 21:27 GMT
Chris,
>I made that change as you suggested, but I still get the same behavior.
Bummer. The only other difference I see is that the VB declaration has
the Auto keyword meaning it will call SendMessageW on NT based
systems, whereas the C# declaration will call SendMessageA. I don't
see why that would make a difference though.
To ask the obvious, do you set HDITEM.mask correctly before the call?
Can you post some short (but complete) code sample that will reproduce
the behavior?
Mattias

Signature
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.