By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,426 Members | 3,368 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,426 IT Pros & Developers. It's quick & easy.

Help with TreeView custom sort callback marshalling?

P: n/a
I need to do a custom sort on a TreeView. I have various object types
associated with the TreeNode Tag property. I want to sort objects of
the same type at the top of the list, other objects at the bottom. I
found some scraps of code in various postings that I am trying to get to
work.

I can not seem to get any meaningful data back from the CompareFunc
callback. According to MSDN, The lParam1 and lParam2 parameters
correspond to the lParam member of the TVITEM structure for the two
items being compared. Does this correspond to the TreeNode Text or Tag
property?

Anyway, I am not certain what data types these are but I tried using
Marshal.PtrToStringAuto which returned null strings.

Thanks in advance for any tips or direction,

-Ed

using System.Runtime.InteropServices;

namespace TreeViewSort
{
public class TreeViewEx : TreeView
{
public const int TV_FIRST = 0x1100;
public const int TVM_SORTCHILDRENCB = TV_FIRST + 21;

public delegate int CompareFuncDelegate (IntPtr lParam1,
IntPtr lParam2,
IntPtr lParamSort);

[StructLayout(LayoutKind.Sequential)]
public struct TVSORTCB
{
public IntPtr hParent;
[MarshalAs(UnmanagedType.FunctionPtr)]
public CompareFuncDelegate lpfnCompare;
public IntPtr lParam ;
}

public TreeViewEx()
{
}

private int CompareFunc(IntPtr lParam1,
IntPtr lParam2,
IntPtr lParamSort)
{
// How do I convert lParams into something I can compare?
// Marshal.PtrToStringAuto returns null strings
string str1 = Marshal.PtrToStringAuto(lParam1);
string str2 = Marshal.PtrToStringAuto(lParam2);
return 0;
}

public void Sort()
{
// Build and send the sort message
TVSORTCB sort;
sort.hParent = base.Nodes[0].Handle;
sort.lpfnCompare = new CompareFuncDelegate(this.CompareFunc);
sort.lParam = IntPtr.Zero;

IntPtr ptrTVSORTCB = Marshal.AllocHGlobal(Marshal.SizeOf(sort));
Marshal.StructureToPtr(sort,ptrTVSORTCB,false) ;

Message msg = Message.Create(base.Handle,
TVM_SORTCHILDRENCB,
IntPtr.Zero,
ptrTVSORTCB);
base.WndProc(ref msg);

Marshal.FreeHGlobal(ptrTVSORTCB);
this.Refresh();
}
}
}

Nov 16 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Ed,
Does this correspond to the TreeNode Text or Tag property?


No I don't think it does. As far as I can tell, the winforms TreeView
control doesn't set the lParam value at all. Instead, it uses an
internal hashtable indexed by node handle to lookup the corresponding
TreeNode object.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 16 '05 #2

P: n/a
Mattias,

Thank you very much for your reply.
Does this correspond to the TreeNode Text or Tag property?

No I don't think it does. As far as I can tell, the winforms TreeView
control doesn't set the lParam value at all. Instead, it uses an
internal hashtable indexed by node handle to lookup the corresponding
TreeNode object.


It sounds like I am at a dead end and my approach to creating a custom
sortable TreeView can not work.

Does anyone have any alternative approaches for creating a custom
sortable TreeView?

Thanks again,

-Ed
Nov 16 '05 #3

P: 1
declare a struct which will hold the tree node item.
public struct TVITEM
{
int mask;
public IntPtr hItem;
int state;
int stateMask;
IntPtr pszText;
IntPtr cchTextMax;
int iImage;
int iSelectedImage;
int cChildren;
int lParam;
}


inside your compare function you can use
TVITEM str1 = (TVITEM)Marshal.PtrToStructure(lParam1, typeof(TVITEM));
TVITEM str2 = (TVITEM)Marshal.PtrToStructure(lParam2, typeof(TVITEM));

Finally you can recover the treeview using
TreeView Tv = (TreeView) TreeView.FromHandle(yourtreeviewinstance.Handle)
Re-cover the treenode using TreeNode Tn = TreeNode.FromHandle(str1.hItem);

now you have the Tn.Text which is a string for comparision.
Jul 17 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.