Note that there are some explanatory texts on larger screens.

plurals
  1. POC# p/invoke, Reading data from an Owner Drawn List Box
    text
    copied!<p>I have an Owner Drawn List Box in an external application (<em>America Online</em>) that I need to get data out of for building a component to assist people with its usability. (the utility will be making access of certain things more simple, etc). </p> <h2>Notice</h2> <p>My knowledge of C++ is <strong>very poor</strong>. I am a C# programmer. </p> <p>I have the <code>hWnd</code> to the List Box in question, but it appears to be owner drawn. Using <code>LB_GETTEXT</code> returns bad data, I just get junk (it renders in my debugger as a bunch of chinese characters) and going through <code>LB_GETITEMDATA</code> returns much the same. </p> <p>I believe this is because the owner drawn list box has graphics on it. Doing <strong>a lot</strong> of digging, I have discovered others in the past with this problem. I have unearthed the following code that is supposed to remedy this issue. However it does not. The code is posted below, and the issues beneath it.</p> <pre><code>void GetListItemData( HWND hListWnd, long index, char *outputResult ) { int result; DWORD processID; HANDLE hProcess; char *itemData; char sDataRead[5]; DWORD bytes; DWORD lListItemHold, lListItemDataHold; *outputResult=0; if( hListWnd ) { GetWindowThreadProcessId( hListWnd, &amp;processID ); hProcess=OpenProcess( 0x10|0xf0000|PROCESS_VM_READ, 0, processID ); if( hProcess ) { lListItemHold=(DWORD)SendMessage( hListWnd, LB_GETITEMDATA, index-1, 0 ); lListItemHold=lListItemHold+24; result=ReadProcessMemory( hProcess, (void *)lListItemHold, &amp;sDataRead, 4, &amp;bytes ); if( !result ) { RaiseWinErr(); } memcpy( &amp;lListItemDataHold, &amp;sDataRead, 4 ); lListItemDataHold=lListItemDataHold+6; ReadProcessMemory( hProcess, (void *)lListItemDataHold, outputResult, 16, &amp;bytes ); CloseHandle( hProcess ); } } } </code></pre> <p>My understanding, limited as it is, is that <code>lListItemHold=lListItemHold+24</code> tries to account for whatever 'structure' is in the ListBox and pass through the first 24 bytes of it, and return what remains. However this does not seem to be working for me. </p> <p>Can anyone shed some light on things I could try? I know I am grasping at straws as it is. I am coding this in C#, so this function is used using <code>p/invoke</code> such as follows;</p> <pre><code> [DllImport("GetListItemData.dll", CallingConvention = CallingConvention.Cdecl)] internal static extern void RetrieveListItem( System.IntPtr hWnd, System.Int32 index, [MarshalAs(UnmanagedType.LPArray)]byte[] buffer ); [DllImport("GetListItemData.dll", CallingConvention = CallingConvention.Cdecl)] internal static extern void RetrieveListItem( System.IntPtr hWnd, System.Int32 index, [MarshalAs(UnmanagedType.LPTStr)]System.Text.StringBuilder buffer ); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload