Getting items from an MFC list control from .NET.

I have a C # application that should get a bunch of information from another window written in C ++ using MFC. The C # application is a plugin for a product containing this other window, so they both work in the same process.

This other window contains a number of fields from which I successfully received the lines by calling:

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

But it also contains 2 list controls that can contain multiple rows of data, each of which contains multiple columns.

How to get this data?

Is there another function in user32.dll that I should use?

Can you get a handle to a list control using:

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

and then somehow injected it into a .NET control to get rows and columns from?

+4
source share
1 answer

This is actually surprisingly difficult. The LVM_ * messages that you would use to retrieve data from listview controls are considered custom messages, and their parameters cannot be distributed across process boundaries using standard Win32 calls.

There are ways to do this - you need to enter the code into the remote process (using, say, CreateRemoteThread), and then use this remote thread to perform the operation and write the results to shared memory - but they are not trivial, and I do not have a good example code for you .

Edit: Well, if you are in the same process, you should be able to do the job. Here is some code (extracted from this article ) that uses LVM_ * messages to extract selected text from a list control. This should make you go in the right direction. There is also an article that has similar code. He could not get it to work due to the cross-border of the process, but it may work for you.

 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; } 
+3
source

All Articles