协助将commctrl命令移植到C# 在C++应用程序中,我有一个指向第三方进程中运行的窗口的HWND。此窗口包含扩展COM TreeView控件的控件。我对获取此控件的CheckState感兴趣。 我使用hWnd从commctrl.h使用TreeView_GetRoot(hWnd)获取HTREEITEM
hwnd指向窗口,hItem是TreeView_GetRoot(hwnd)的返回值。它们的用途如下:协助将commctrl命令移植到C# 在C++应用程序中,我有一个指向第三方进程中运行的窗口的HWND。此窗口包含扩展COM TreeView控件的控件。我对获取此控件的CheckState感兴趣。 我使用hWnd从commctrl.h使用TreeView_GetRoot(hWnd)获取HTREEITEM,c#,com,treeview,C#,Com,Treeview,hwnd指向窗口,hItem是TreeView_GetRoot(hwnd)的返回值。它们的用途如下: int iCheckState = TreeView_GetCheckState(hwnd, hItem); switch (iCheckState) { case 0: // (unchecked) case 1: // checked ... } 我希望将这段代码移植到一个C#应用程序中,该应用程序也能做同样的事情(关闭TreeView控件的Ch
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#中重新创建此代码:(
建议?为什么不使用Windows Forms TreeView控件?如果使用此控件,请将该控件的CheckBox属性设置为true以启用复选框,并将要显示的节点上的Checked属性设置为Checked
要获取根节点的集合,请使用TreeView的nodes属性。这将返回一个TreeNodeCollection,然后您可以对其进行索引或添加项。我们从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_用户+消息。当这些消息跨进程发送时,数据参数的地址
未经修改,因此产生的进程可能会导致访问冲突。这在任何情况下都是一个问题
你使用的语言(C++或C语言),所以也许我错了(你说你有一个工作C++程序)。
静态类互操作{
公共静态IntPtr TreeView_SetCheckState(HandleRef hwndTV、IntPtr hti、bool fCheck){
返回TreeView_SetItemState(hwndTV、hti、IndexStateImageMask((fCheck)?2:1),(uint)TVIS.TVIS_STATEIMAGEMASK);
}
公共静态IntPtr树视图设置项状态(HandleRef hwndTV、IntPtr hti、uint数据、uint掩码){
tviitem _ms_TVi=新的tviitem();
_ms_TVi.mask=(uint)TVIF.TVIF_状态;
_ms_TVi.hItem=(hti);
_ms_TVi.stateMask=(_mask);
_ms_TVi.state=(数据);
IntPtr p=Marshal.alloctaskmem(Marshal.SizeOf(_ms_TVi));
Marshal.StructureToPtr(_ms_TVi,p,false);
IntPtr r=发送消息(hwndTV,(int)TVM.TVM_SETITEMW,IntPtr.Zero,p);
弗里科塔斯克梅姆元帅(p);
返回r;
}
私有静态uint INDEXTOSTATEIMAGEMASK(int i){return((uint)(i)windows由第三方所有。我无法控制它。此应用程序的制造商已选择使用COM对象的扩展来实现该控制。
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;
}
}