2011-06-08 14 views
4

MFCを使用してC++で記述された別のウィンドウから多数の情報を取得する必要があるC#アプリケーションがあります。 C#アプリはこの他のウィンドウを含む製品へのプラグインなので、両方が同じプロセス内で実行されています。.NETからのMFCリストコントロールから項目を取得する

は、この他のウィンドウには、呼び出すことによって、私は成功したから文字列を得ているフィールドの数が含まれています

[DllImport("user32.dll", SetLastError = true)] 
     public static extern uint GetDlgItemText(IntPtr hDlg, int nIDDlgItem, [Out] StringBuilder lpString, int nMaxCount); 

をしかし、それはまた、各のデータの行数が含まれていてもよい2つのリストコントロールが含まれています列の数。

このデータを取得するにはどうすればよいですか?

user32.dllに別の機能がありますか?

使用して、リストコントロールのハンドルを取得することができます。

[DllImport("User32", SetLastError = true)] 
     public static extern IntPtr GetDlgItem(IntPtr hwndParent, int ItemId); 

、その後、何らかの形であなたから行と列を取得することができます.NETコントロールにそれをキャストしますか?

答えて

3

これは実際には驚くほど困難です。リストビューコントロールからデータを取得するために使用するLVM_ *メッセージは、ユーザー定義のメッセージとみなされ、標準のWin32呼び出しを使用して、そのパラメータをプロセス境界全体にマーシャリングすることはできません。

ありがこれを達成する方法いる - 一つはリモートプロセスにコードを注入することである(たとえば、CreateRemoteThreadを使用して)、次いで、リモートスレッドが操作を実行し、共有メモリに結果を書き込むことがある - しかし、彼ら私はあなたのための良いコードの例を持っていません。

編集:OK、同じプロセスであれば、この作業を行うことができます。 LVM_ *メッセージを使用してリストコントロールから選択したテキストを抽出するコード(this articleから抜粋)があります。これは正しい方向に進むためのものです。同様のコードを持つ記事hereもあります。彼はプロセスの境界を超えて働くことができませんでしたが、それはあなたのために働くかもしれません。

private string GetSelectedItem() 
{ 
    string item = null; 

    IntPtr pStringBuffer = Marshal.AllocHGlobal(2048); 
    IntPtr pItemBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LVITEM))); 

    int selectedItemIndex = SendMessage(base.Handle, LVM_GETNEXTITEM, (IntPtr)(-1), (IntPtr)LVNI_SELECTED).ToInt32(); 
    if (selectedItemIndex > -1) 
    { 
     LVITEM lvi = new LVITEM(); 
     lvi.cchTextMax = 1024; 
     lvi.pszText = pStringBuffer; 
     Marshal.StructureToPtr(lvi, pItemBuffer, false); 
     int numChars = SendMessage(base.Handle, LVM_GETITEMTEXT, (IntPtr)selectedItemIndex, pItemBuffer).ToInt32(); 
     if (numChars > 0) 
     { 
      item = Marshal.PtrToStringUni(lvi.pszText, numChars); 
     } 
    } 

    Marshal.FreeHGlobal(pStringBuffer); 
    Marshal.FreeHGlobal(pItemBuffer); 

    return item; 
} 

struct LVITEM 
{ 
    public int mask; 
    public int iItem; 
    public int iSubItem; 
    public int state; 
    public int stateMask; 
    public IntPtr pszText; 
    public int cchTextMax; 
    public int iImage; 
    public IntPtr lParam; 
    public int iIndent; 
    public int iGroupId; 
    int cColumns; // tile view columns 
    public IntPtr puColumns; 
    public IntPtr piColFmt; 
    public int iGroup; 

} 
+0

私は同じプロセス内で実行しています。私は既存の製品へのプラグインを開発しました。私は、私が信じているWin32呼び出しを使用する以外の他のウィンドウへのプログラムによるアクセス権を持っていません。この場合にLVM_ *メッセージを使用する方法の例は、非常に高く評価されます。 – TerryB

+0

ああ、クール!この情報に基づいて編集された回答。 – mwigdahl

関連する問題