2011-06-08 93 views
4

我有一個C#應用程序,需要從使用MFC編寫的另一個使用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的),然後有一個遠程線程執行的操作,並將結果寫入到共享存儲器中 - 但它們是不平凡的,我沒有很好的例子代碼給你。

編輯:好的,如果你是同一個過程你應該能夠做到這一點。以下是一些代碼(從this article開始),它使用LVM_ *消息從列表控件中提取選定的文本。這應該讓你朝着正確的方向前進。還有一篇文章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 2011-06-08 23:48:37

+0

哦,很酷!根據此信息編輯回答。 – mwigdahl 2011-06-09 16:25:19

相關問題