在C ++应用程序中,我有一个hWnd指向在第三方进程中运行的窗口。 该窗口包含扩展COM TreeView控件的控件。 我有兴趣获取此控件的CheckState。
我使用hWnd从commctrl.h使用TreeView_GetRoot(hwnd)获取HTREEITEM

hwnd指向窗口,hItem是TreeView_GetRoot(hwnd)的返回值。 它们的用法如下:

int iCheckState = TreeView_GetCheckState(hwnd,  hItem);
switch (iCheckState)
{
   case 0:
      // (unchecked)
   case 1:
      // checked
   ...
}

我正在寻找将此代码移植到执行相同功能的C#应用​​程序中(关闭TreeView控件的CheckState)。 我从未使用过COM,并且对此很陌生。

我尝试使用.NET mscomctl,但是找不到与TreeView_GetRoot或TreeView_GetCheckState等效的方法。 我完全陷入困境,不知道如何在C#中重新创建此代码:(

建议?

===============>>#1 票数:2 已采纳

我们从CommCtrl.h中获得了以下定义:

#define TreeView_SetItemState(hwndTV, hti, data, _mask) \
{ TVITEM _ms_TVi;\
  _ms_TVi.mask = TVIF_STATE; \
  _ms_TVi.hItem = (hti); \
  _ms_TVi.stateMask = (_mask);\
  _ms_TVi.state = (data);\
  SNDMSG((hwndTV), TVM_SETITEM, 0, (LPARAM)(TV_ITEM *)&_ms_TVi);\
}

#define TreeView_SetCheckState(hwndTV, hti, fCheck) \
  TreeView_SetItemState(hwndTV, hti, INDEXTOSTATEIMAGEMASK((fCheck)?2:1), TVIS_STATEIMAGEMASK)

我们可以使用PInvoke将其转换为C#。 首先,我们将这些宏作为函数实现,然后添加使这些函数正常工作所需的任何其他支持。 这是我的第一枪。 您应该仔细检查我的代码,尤其是在处理结构体时。 此外,您可能想发布消息跨线程而不是调用SendMessage。

最后,我不确定这是否会成功,因为我相信通用控件会使用WM_USER +消息。 当这些消息跨进程发送时,数据参数的地址未修改,并且所产生的进程可能会导致访问冲突。 无论使用哪种语言(C ++或C#),这都是一个问题,所以也许我在这里是错误的(您说您有一个运行中的C ++程序)。

static class Interop {

public static IntPtr TreeView_SetCheckState(HandleRef hwndTV, IntPtr hti, bool fCheck) {
    return TreeView_SetItemState(hwndTV, hti, INDEXTOSTATEIMAGEMASK((fCheck) ? 2 : 1), (uint)TVIS.TVIS_STATEIMAGEMASK);
}

public static IntPtr TreeView_SetItemState(HandleRef hwndTV, IntPtr hti, uint data, uint _mask) {
    TVITEM _ms_TVi = new TVITEM();
    _ms_TVi.mask = (uint)TVIF.TVIF_STATE;
    _ms_TVi.hItem = (hti);
    _ms_TVi.stateMask = (_mask);
    _ms_TVi.state = (data);
    IntPtr p = Marshal.AllocCoTaskMem(Marshal.SizeOf(_ms_TVi));
    Marshal.StructureToPtr(_ms_TVi, p, false);
    IntPtr r = SendMessage(hwndTV, (int)TVM.TVM_SETITEMW, IntPtr.Zero, p);
    Marshal.FreeCoTaskMem(p);
    return r;
}

private static uint INDEXTOSTATEIMAGEMASK(int i) { return ((uint)(i) << 12); }

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(HandleRef hWnd, int msg, IntPtr wParam, IntPtr lParam);

private enum TVIF : uint {
    TVIF_STATE = 0x0008
}

private enum TVIS : uint {
    TVIS_STATEIMAGEMASK = 0xF000
}

private enum TVM : int {
    TV_FIRST = 0x1100,
    TVM_SETITEMA = (TV_FIRST + 13),
    TVM_SETITEMW = (TV_FIRST + 63)
}

private struct TVITEM {
    public uint mask;
    public IntPtr hItem;
    public uint state;
    public uint stateMask;
    public IntPtr pszText;
    public int cchTextMax;
    public int iImage;
    public int iSelectedImage;
    public int cChildren;
    public IntPtr lParam;
}
}

===============>>#2 票数:1

为什么不使用Windows窗体TreeView控件? 如果使用此控件,请将控件的CheckBoxes属性设置为true以启用复选框,然后在要显示选中状态的节点上设置Checked属性。

要获取根节点的集合,请使用TreeView的Nodes属性。 这将返回一个TreeNodeCollection,您可以将其编入索引或添加项目。

  ask by Kenn translate from so

未解决问题?本站智能推荐:

5回复

带有CheckBoxes的TreeView在c#中

我有一个带有c#复选框的树视图,我希望当用户检查一个节点时,自动检查下面级别上的所有节点。 每次用户检查某个节点时,是否有人知道如何在没有在所有树上运行recorsive fnction的情况下执行此操作? 谢谢 //这个函数返回treeView。
1回复

传递对象C#和.NET

我是C#的新手,语法和传递对象时遇到问题。 我正在建立一个具有商店树状视图和每个商店客户列表视图的表单。 当我单击表单上的按钮时,将调用“ OnStoreAdd”并创建商店对象。 如何将该对象传递给“ AddStoreNode(object?tag?)”? 我不知道如何将新的存储对
2回复

C#可编辑TreeViewItem

我想要可编辑的根TreeViewItem,为此我创建了Event 在C#中: 但是我有两个问题: 1)此代码不会更改TextBlock上的Header 2)此XAML对所有项目都设置了事件,我只想编辑根项目... 感谢帮助!
3回复

标准Treeview的C#替换?

我想找一个提供System.Windows.Form.Treeview的替代品。 我需要以下改进: 多项选择 更好的性能(标准小部件的性能非常糟糕,特别是在添加一长串项目时) 在树视图窗口小部件中拖放项目时滚动 我可能会忘记一些,但这些非常重要。 由于我已经
1回复

C#后期绑定命令COM obj命令由于所需的回写设置而失败

我知道我应该在Vb.net中编写此代码,但是由于我自己的原因,我试图在C#.net Framework 3.5中晚对Com对象进行绑定。 我得到的错误是“ DISP_E_BADCALLEE”,而我仅根据将所需的复本设置为true时得到此错误。 我正在处理安全问题吗? 我的研究使我尝试在As
1回复

TreeView C#文件路径

我在查看SelectedTreeView的路径时遇到问题。 结果是:System.Windows.Controls.TreeView标题: FILENAME s.Count:1 我需要一个文件路径,因为我将TreeView用作文件浏览器,并且,如果我想从treeview中运行文件,
2回复

关于c#中的树控件

这是我从数据库中检索数据并在Tree控件中显示它的代码 我在这一行得到错误: 错误:'System.Web.UI.WebControls.TreeNodeCollection.Add(System.Web.UI.WebControls.TreeNode)'的最佳重载方法匹配具
2回复

C#树视图索引

我在Treeview以及节点索引的工作方式上遇到了一些问题。 在我的程序中,我有一个可以包含任意数量用户的数据库。 每个用户由回车符分隔(即每行一个用户)。 我正在创建一个列出数据库中所有用户的treeview对象。 如果用户单击特定节点,那么在我从数据库中动态创建节点时,如何引用该节点
3回复

在c#中添加复选框在c#中

我想在我的应用程序的树视图中将复选框添加到某个父节点的子节点...我该如何添加它?
2回复

C#中的TreeView和ListView

我有一个TreeView,它显示计算机上的所有文件夹。 如何查看TreeView中特定文件夹中的所有文件?