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);
}
UPDATE 1:
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;
}
UPDATE 2:
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:
- Call SendMessage with that HWND and the message LB_GETCOUNT to get the number of items in the list.
- 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.
- 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.
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!
来源:https://stackoverflow.com/questions/18880330/how-can-i-retrieve-the-values-from-window-of-class-thunderrt6listbox-using-use