How can I retrieve the values from window of class “ThunderRT6ListBox” using user32.dll in c#


I am trying to retrieve information from extern desktop aplication in Windows.

I know how extract the text from Textboxes (class "Edit") but I don't know how extract the values from controls with class name "ThunderRT6ListBox" and "ThunderRT6ComboBox". How can I do that?

I have this code to extract the text from the textbox:

public static class ModApi { [DllImport("user32.dll", EntryPoint = "FindWindowA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); [DllImport("user32.dll", EntryPoint = "SendMessageTimeout", SetLastError = true, CharSet = CharSet.Auto)] public static extern uint SendMessageTimeoutText(IntPtr hWnd, int Msg, int countOfChars, StringBuilder text, uint flags, uint uTImeoutj, uint result); [DllImport("user32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] static internal extern bool EnumChildWindows(IntPtr hWndParent, funcCallBackChild funcCallBack, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, StringBuilder lParam); const int LB_GETCOUNT = 0x018B; const int LB_GETTEXT = 0x0189; public static string GetText(IntPtr hwnd) { var text = new StringBuilder(1024); if (SendMessageTimeoutText(hwnd, 0xd, 1024, text, 0x2, 1000, 0) != 0) { return text.ToString(); } return ""; } } public foo() { IntPtr value = new IntPtr(0x019C086A); //ID locate using Spy++ String caption = ModApi.GetText(value); }


The way to read from ListBox:

public static List<string> GetListBoxContents(IntPtr listBoxHwnd) { int cnt = (int)SendMessage(listBoxHwnd, LB_GETCOUNT, IntPtr.Zero, null); List<string> listBoxContent = new List<string>(); for (int i = 0; i < cnt; i++) { StringBuilder sb = new StringBuilder(256); IntPtr getText = SendMessage(listBoxHwnd, LB_GETTEXT, (IntPtr)i, sb); listBoxContent.Add(sb.ToString()); } return listBoxContent; }


The way to read from ComboBox:

public static List<string> GetComboBoxContents(IntPtr cbBoxHwnd) { int cnt = (int)SendMessage(cbBoxHwnd, CB_GETCOUNT, IntPtr.Zero, null); List<string> listBoxContent = new List<string>(); for (int i = 0; i < cnt; i++) { //int txtLength = SendMessage(cbBoxHwnd, CB_GETLBTEXTLEN, i, 0); StringBuilder sb = new StringBuilder(256); IntPtr getText = SendMessage(cbBoxHwnd, CB_GETLBTEXT, (IntPtr)i, sb); listBoxContent.Add(sb.ToString()); } return listBoxContent; }


You're dealing with a VB6 application from eons ago. "Thunder" was the internal name for the VB product/project (trivial side note).

You're closer than you realize. If you have the HWND to the control, and I think you do:

<ol><li>Call SendMessage with that HWND and the message LB_GETCOUNT to get the number of items in the list.</li> <li>For each index, call SendMessage with LB_GETTEXTLEN and the current item index to get the length of the text, then allocate a buffer accordingly.</li> <li>Call SendMessage again, this time using LB_GETTEXT message, same item index (zero-based), and the reference to your buffer, and that should get you each item's text.</li> </ol>

You might consider one more declaration/alias to SendMessage that just returns an int, which should make some of these calls simpler.

If I get a chance, I will clean this up a bit later with a more specific code example (or at least pseudocode), but I get the impression you're very much on the right track already and may only need this basic description to get the rest of the way.

Good luck!


  • Thread.Join on multiple threads with timeout
  • “Undefined reference” trying to reference an static field
  • Extend Codeigniter Exceptions class to add a custom method
  • Google App Indexing not resolving for Swift?
  • getting empty value in viewWillAppear( ) but getting valid value in viewDidLoad( )
  • Pass a custom comparator through a function
  • C# Dictionary ContainsKey
  • How to map childs/parent class with petapoco?
  • Getting push notification payload when user opens app manually after push has been received in the b
  • Change color of row programmatically in WatchKit
  • Linked list in C, no member error
  • Conditional serialization with protobuf-net
  • Ambiguous action methods in MVC 2
  • Can someone explain the exact use of interfaces in C#?
  • WebSphere MQ 6 message segmentation option ignored in put()?
  • Auto Height of UICollectionView inside UITableViewCell
  • Member function pointer cast, from Derived to Base class
  • Unable to use dot layout (graphviz as a library)
  • Is the Go HTTP handler goroutine expected to exit immediately in this case?
  • how to save bool value in KeychainItemWrapper
  • Load 24 bit TGA
  • Cannot connect to native local socket on android 5.1
  • PHP file_exists() anomaly
  • Generate a unique string based on a pair of strings
  • Deleting a widget from QTableView
  • What is the undocumented SessionIdInterface in PHP 5.5?
  • multidatatrigger with multibinding in ControlTemplate.Triggers
  • Is there a parser equivalent of 'fragment' marking in ANTLR4?
  • Is it possible to run clang with llc flags
  • aapt.exe'' finished with non-zero exit value 1
  • Clear activity stack before launching another activity
  • Build Successful but not running on simulator
  • Android app gives error “BatteryStatsImpl: reading network stats”
  • How to run “Deployd” on port 80 instead of port 5000 in webserver.
  • SignalR .NET Client Invoke throws an exception
  • Numpy divide by zero. Why?
  • php design question - will a Helper help here?
  • AngularJs get employee from factory
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Authorize attributes not working in MVC 4