Frage

In einem C ++ app, ich habe ein hWnd zu einem Fenster zeigt in einem Dritten Prozess ausgeführt wird. Dieses Fenster enthält Steuerelemente die die COM TreeView Steuer erstrecken. Ich interessiere mich für die Checkstate dieser Steuerung zu erhalten.
Ich verwende die hWnd eine HTREEITEM erhalten mit TreeView_GetRoot (hwnd) von commctrl.h

Hwnd zeigt auf das Fenster und hItem ist Rückgabewert von TreeView_GetRoot (hwnd). Sie werden wie folgt verwendet:

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

Ich bin auf der Suche nach Port diesen Code in eine C # -Anwendung, die die gleiche Sache tut (schaltet die Checkstate der TreeView Steuerung aus). Ich habe noch nie COM verwendet und bin ganz fremd.

Ich habe versucht, das .NET mscomctl verwenden kann aber gleichwertiges Verfahren zu TreeView_GetRoot oder TreeView_GetCheckState nicht finden. Ich bin total fest und weiß nicht, wie dieser Code in C # erstellen: (

Verbesserungsvorschläge?

War es hilfreich?

Lösung

Wir haben diese Definitionen von 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)

Wir können dies auf C # übersetzen PInvoke verwenden. Zunächst setzen wir diese Makros als Funktionen, und fügen Sie dann was auch immer andere Unterstützung benötigt wird, um diese Funktionen arbeiten zu machen. Hier ist mein erster Schuss auf ihn. Sie sollten wirklich sicherstellen, meine Code vor allem, wenn es um die Rangierung der Struktur. Ferner können Sie die Nachricht verkanten stellen anstelle von Sendmessage aufrufen.

Schließlich bin ich nicht sicher, ob dies überhaupt funktionieren wird, da ich glaube, dass die gemeinsame Steuerelemente verwendet WM_USER + Nachrichten. Wenn diese Nachrichten Quer Prozess gesendet, die Adressen der Datenparameter sind unmodifizierte, und der resultierende Prozess eine Zugriffsverletzung verursachen kann. Dies wäre ein Problem in was auch immer Sprache (C ++ oder C #) verwenden, ich falsch so vielleicht bin hier (Sie sagen, Sie über eine funktionierende C ++ Programm haben).

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;
}
}

Andere Tipps

Warum verwenden Sie keine Windows TreeView Forms-Steuerelement? Wenn Sie dieses Steuerelement verwenden, stellen Sie die Kontrollkästchen Eigenschaft des Steuerelements auf true Kontrollkästchen zu aktivieren, und stellen Sie die Eigenschaft Checked auf den Knoten Sie überprüft angezeigt werden soll.

Um die Sammlung von Root-Knoten zu erhalten, verwenden Sie den Knoten-Eigenschaft des TreeView. Dies gibt eine TreeNodeCollection die Sie dann Index oder Elemente hinzuzufügen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top