public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
Dictionary<int, TreeNode> map = new Dictionary<int, TreeNode>();
for (int i = 0; i < 100; i++)
{
TreeNode node = new TreeNode(i.ToString());
if (i % 10 == 0)
_tree.Nodes.Add(node);
map.Add(i, node);
if (i % 10 != 0)
{
map[Convert.ToInt32(Math.Floor(i / 10.0)) * 10].Nodes.Add(node);
node.SetNodeHeight(2);
}
}
}
}
public static class TreeViewExtendMethod
{
[StructLayout(LayoutKind.Sequential)]
struct TVITEMEX
{
public Mask mask;
public IntPtr item;
public uint state;
public uint stateMask;
public IntPtr pszText;
public int cchTextMax;
public int iImage;
public int iSelectedImage;
public int iChildren;
public IntPtr lParam;
public int iIntegral;
// ... plus some windows 6+ crap
}
[Flags]
enum Mask : uint
{
Text = 1,
Image = 2,
Param = 4,
State = 8,
Handle = 16,
SelectedImage = 32,
Children = 64,
Integral = 128,
}
public static int GetNodeHeight(this TreeNode tn)
{
TVITEMEX tvix = new TVITEMEX();
tvix.mask = Mask.Handle | Mask.Integral;
tvix.item = tn.Handle;
tvix.iIntegral = 0;
IntPtr hParam=Marshal.AllocHGlobal(Marshal.SizeOf(tvix));
Marshal.StructureToPtr(tvix, hParam, false);
win32.SendMessage(tn.TreeView.Handle, win32.TVM_GETITEM, IntPtr.Zero, hParam);
return tvix.iIntegral;
}
public static void SetNodeHeight(this TreeNode tn, int height)
{
TVITEMEX tvix = new TVITEMEX();
tvix.mask = Mask.Handle | Mask.Integral;
tvix.item = tn.Handle;
tvix.iIntegral = height;
IntPtr hParam=Marshal.AllocHGlobal(Marshal.SizeOf(tvix));
Marshal.StructureToPtr(tvix, hParam, false);
win32.SendMessage(tn.TreeView.Handle, win32.TVM_SETITEM, IntPtr.Zero, hParam);
}
}
以上是示例代码,在使用PINV手动更改节点高度后,单击滚动条底部时,树形视图将滚动,因为只需单击一下就不会滚动。
首先,我认为它可能是由滚动条引起的,在我将滚动消息段(8)设置为结束滚动后,它没有按预期工作。最后,在捕获滚动消息(0x115)时,退出WndProc,然后它可以工作。我不知道发生了什么,因为我无法找到任何msg可以取消滚动,除了将wParam设置为8肯定不起作用。
答案 0 :(得分:0)
我终于找到了一个解决方案,虽然并不优雅,但它应该有效。 这是解决方案,
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x115)
{
if (((int)m.WParam & 5) == (5) ||
((int)m.WParam & 4) == (4)
)
{
int para = (int)m.WParam;
int temp = (para - (para % 2 == 0 ? 4 : 5)) >> 16;
// store the current position, if the position doesn't change, no need to handle
if (temp == pos)
return;
else
pos = temp;
}
if (((int)m.WParam & 8) == 8)
return;
//Debug.WriteLine(m.WParam);
//if (DisableScroll)
// return;
// //m.WParam = (IntPtr)8;
//SCROLLINFO si = new SCROLLINFO();
//si.cbSize = Marshal.SizeOf(si);
//si.fMask = (int)(ScrollInfoMask.SIF_POS | ScrollInfoMask.SIF_PAGE | ScrollInfoMask.SIF_RANGE | ScrollInfoMask.SIF_TRACKPOS);
//GetScrollInfo(this.Handle, 1, ref si);
////Debug.WriteLine(string.Format("Max pos:{0}, Min pos: {1}", si.nMin, si.nMax));
//Debug.WriteLine(string.Format("wParam:{0} hParam:{1}", m.WParam, m.LParam));
//Debug.WriteLine(string.Format("It page size: {0}, position: {1}, range: {2}, track pos: {3}", si.nPage, si.nPos, si.nPage, si.nTrackPos));
//if (si.nPage + Math.Max(si.nPos, si.nTrackPos) >= si.nMax)
//{
// return;
//}
}
base.WndProc(ref m);
}