2008-09-16 25 views
1

C++アプリケーションでは、第三者プロセスで実行されているウィンドウを指すhWndを持っています。このウィンドウには、COM TreeViewコントロールを拡張するコントロールが含まれています。私はこのコントロールのCheckStateを取得することに興味があります。
IウィンドウにC#への移植指示commctrlコマンド

commctrl.h HWNDポイントからTreeView_GetRoot(HWND)を使用してHTREEITEMを取得するためのhWndを使用しhItemはTreeView_GetRoot(HWND)からの戻り値です。私は同じことを(TreeViewコントロールのにcheckStateをオフ)C#のアプリにポートにこのコードを探しています

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

次のように彼らが使用されています。私はCOMを一度も使ったことがなく、まったく馴染みがない。

.NET mscomctlを使用しようとしましたが、TreeView_GetRootまたはTreeView_GetCheckStateと同等のメソッドが見つかりません。私は完全にこだわっているとC#:(

提案でこのコードを再作成する方法がわからない?

答えて

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

これはうまくいきました。 – Kenn

1

あなたは、このコントロールを使用している場合は、なぜあなたは?WindowsフォームTreeViewコントロールを使用していない、設定コントロールのCheckBoxesプロパティをtrueに設定してチェックボックスをオンにし、表示するノードのCheckedプロパティをチェックします。

ルートノードのコレクションを取得するには、TreeViewのNodesプロパティを使用します。次にTreeNodeCollectionを返します。または項目を追加する。

+0

ウィンドウは第三者が所有しています。私はそれを支配していない。このアプリケーションのメーカーは、COMオブジェクトの拡張機能を使用してコントロールを実装することを選択しました。 – Kenn

関連する問題