2008-09-16 20 views
1

Bir C++ uygulamasında, bir üçüncü taraf işleminde çalışan bir pencereyi gösteren bir hWnd var. Bu pencere COM TreeView denetimini genişleten denetimleri içerir. Bu kontrolün CheckState'ini almakla ilgileniyorum.
Pencerenin commctrl.hYardım portu commctrl komutları için C#

HWND noktalarından TreeView_GetRoot (HWND) kullanılarak bir HTREEITEM için hWnd kullanımı ve Hitem TreeView_GetRoot (HWND) gelen dönüş değerdir. Ben aynı şeyi yapar (TreeView denetimini checkState kapanır) bir C# uygulaması içine portuna bu kodu arıyorum

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

şu şekildedir: Onlar kullanılmaktadır. Hiç COM kullanmadım ve oldukça yabancıyım.

.NET mscomctl kullanmayı denedim ancak TreeView_GetRoot veya TreeView_GetCheckState öğelerine eşdeğer yöntemler bulamıyorum. Tamamen sıkıştım ve C# :(

Öneriler Bu kodu yeniden nasıl bilmiyorum?

cevap

2

Bu tanımlamalar CommCtrl.h adresinden elde edilmiştir:

#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) 

Bunu PInvoke kullanarak C# 'ya çevirebiliriz. İlk olarak, bu makroları fonksiyonlar olarak uyguluyoruz ve daha sonra bu fonksiyonların çalışması için başka bir desteğe ihtiyaç duyduğunuzu ekliyoruz. İşte ilk atışım bu. Özellikle kodumu, yapının dizilişine gelince iki kez kontrol etmelisiniz. Dahası, SendMessage'i çağırmak yerine iletiyi çapraz iş parçacığı gönderebilirsiniz.

Son olarak, genel denetimlerinin WM_USER + iletilerini kullandığını düşündüğümden bu durumun işe yarayıp yaramayacağından emin değilim. Bu mesajlar çapraz süreç olarak gönderildiğinde, veri parametre adresleri adresleri değiştirilmez ve sonuçta oluşan işlem Erişim İhlaline neden olabilir. Bu, kullandığınız dilinde (C++ veya C#) bir sorun olacaktır, bu yüzden belki de burada yanılıyorum (çalışma C++ programınız var).

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

Evet, işe yaradı. – Kenn

1

Eğer bu kontrolü kullanıyorsanız Neden? Bir Windows Forms TreeView denetimi kullanmıyorsanız, set kontrolü en Onay kutularını etkinleştirmek için onay kutularını true olarak işaretleyin ve görüntülemek istediğiniz düğümlerdeki Checked özelliğini ayarlayın.

Kök düğümlerini toplamak için TreeView'un Düğümleri özelliğini kullanın. Böylece TreeNodeCollection değerini döndürebilirsiniz. veya öğeleri ekleyin

+0

Pencereler bir üçüncü tarafa aittir. Üzerinde hiçbir kontrolüm yok. Bu uygulamanın üreticisi, COM nesnesinin bir uzantısını kullanarak denetimi uygulamak için seçti. – Kenn