Domanda

In C++ app, ho un hWnd che punta a una finestra in esecuzione in un terzo processo.Questa finestra contiene i controlli che si estendono COM controllo TreeView.Io sono interessato a ottenere la CheckState di questo controllo.
Io uso l'hWnd per ottenere un HTREEITEM utilizzando TreeView_GetRoot(hwnd) da commctrl.h

hwnd punti alla finestra e hItem è il valore restituito dalla TreeView_GetRoot(hwnd).Sono utilizzati come segue:

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

Sto cercando di porto questo codice in C# app che fa la stessa cosa (si spegne il CheckState del controllo TreeView).Non ho mai utilizzato COM e sono del tutto sconosciuti.

Ho provato con il .NET mscomctl ma non riesco a trovare metodi equivalenti per TreeView_GetRoot o TreeView_GetCheckState.Mi sono completamente bloccato e non so come ricreare questo codice in C# :(

Suggerimenti?

È stato utile?

Soluzione

Abbiamo queste definizioni da 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)

Siamo in grado di tradurre questo in C#, utilizzando PInvoke.Primo, dobbiamo attuare queste macro funzioni, e quindi aggiungere qualsiasi cosa altri tipi di supporto è necessario per fare le funzioni di lavoro.Ecco il mio primo colpo.Si dovrebbe controllare due volte mio codice specialmente quando si tratta di smistamento della struttura.Inoltre, è possibile che si desidera inviare il messaggio di cross-thread invece di chiamare SendMessage.

Infine, io non sono sicuro se questo sarà il lavoro a tutti in quanto credo che il comune utilizzare i controlli WM_USER+ messaggi.Quando questi messaggi vengono inviati cross-process, il parametro di dati gli indirizzi di sono modificate e il conseguente processo può causare una Violazione di Accesso.Questo sarebbe un problema in qualsiasi la lingua in uso (C++ o C#), quindi forse ho sbagliato qui (tu dici di avere un programma in 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;
}
}

Altri suggerimenti

Perché non si utilizza un controllo TreeView di Windows Form?Se si utilizza questo controllo, è possibile impostare le Caselle di controllo del controllo di proprietà a true per attivare le caselle di controllo e impostare la proprietà Checked sui nodi che si desidera visualizzare controllato.

Per ottenere la collezione di nodi radice, utilizzare la visualizzazione struttura Nodi della struttura.Questo restituisce un TreeNodeCollection che è quindi possibile indice o aggiungere elementi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top