Hiho,
ich habe mal wieder die Probleme die sonst keiner hat. Ich möchte über C# ein anderes Programm steuern (iBot).
Im Moment hänge ich noch am auslesen von EditBoxen.
Zum Sammeln der Controls verwende ich EnumChildWindows (user32). Die dann alle in einer Liste durchsuche ich nach Strings wie CharName etc. um die richtigen Controls zu finden.
Hier liegt das Problem. Mit GetWindowText hole ich den Text aus den Controls. Es kommt auch Text raus. Nur ist das z.B. beim Charnamen "<None>" obwohl ich eingeloggt bin (Da steht was anderes im GUI).
XX_005 heist mein Testchar. Alles was gefunden wird, ist XX_005 in der Clientless Charauswahl. Aber in der Übersicht auf der ersten Seite nicht.
Da findet er nur <None>. Das AutoIt Window Info zeigt auch nur None an. Und wenn ich den Inhalt des Controls ändere, bleibt in der Form XX_005 stehen, wenn ich dann mit dem Window Info schaue sehe ich den geänderten Text.
Ich habe überhaupt keinerlei Ahnung an was es liegt.
Vielleicht an Win7 x64.
Ich poste einfach mal den Code, evtl fällt euch was auf.
Die iBot-Klasse stammt von der BotClass - Klasse ab. Das ist eine Pseudoklasse, damit ich später mehrere verschiedene Bots in einem Array gleich behandeln kann (Gleiche Methoden, etc)
Es beginnt im Constructor von iBot. Danach versuche ich per iBot-Instanz.Charname den Charname auszulesen woraufhin die MessageBox kommten sollte, und mir den Index des Controls verrät.
Das ist die Klasse die die Daten aus dem iBot holt. In Zeile 64 gehts los.
[cs]
using System;
using System.Diagnostics;
using System.Text;
using AutoItX3Lib;
using System.Windows.Forms;
namespace BotManager
{
/// <summary>
/// Die iBot-Klasse verwaltet den iBot
/// </summary>
class iBot : BotClass
{
/* Infos zum iBot
*
* Wenn man den iBot startet, kommt als erstes die Meldung:
* "Dieser Bot ist kostenlos, botten ist illegal und man soll doch bitte donaten, etc."
*
* Die Process-Klasse des .NET-Framework nimmt dieses Fenster als MainWindow was hier
* nicht brauchbar ist.
*
* Wir verwenden die Funktion EnumWindows um das richtige Fenster zu finden
*/
private Process proc; // Prozess des Bots
private RunningBots.BotInfo GUI; // BotInfo-Struct Instanz zur einfacheren Verwaltung von Informationen
private EnumWindowsItem eWindowsItem;
private enum ControlID : int
{
charname = 334,
guildname,
level,
skillpoints,
experience,
gold,
PosX,
PosY
}
#region Propertys
/// <summary>
/// Gibt den Fenstertitel zurück oder legt diesen fest
/// </summary>
public override string WindowTitle
{
get { return eWindowsItem.Text; }
set { eWindowsItem.Text = value; }
}
#endregion
#region Bot Propertys
/// <summary>
/// Gibt den Namen des Characters zurück (readonly)
/// </summary>
public override string Charname
{
get
{
EnumWindows ewn = new EnumWindows();
ewn.GetWindows(eWindowsItem.Handle);
for(int i = 0; i != ewn.Items.Count - 1;i++)
{
if (ewn.Items[i].Text == "XX_005")
{
MessageBox.Show("Num " + i.ToString() + " " + ewn.Items[i].ClassName);
}
}
return ewn.Items.Count.ToString();
}
}
/// <summary>
/// Gibt den Servernamen zurück (readonly)
/// </summary>
public override string Server
{
get { return GUI.Server; }
}
/// <summary>
/// Gibt das Level des Characters zurück (readonly)
/// </summary>
public override byte Level
{
get { return GUI.Level; }
}
#endregion
#region Constructor
#region Construct by PID
/// <summary>
/// Constructor-Methode
/// </summary>
/// <param name="PID">Prozess-ID des Bot(-prozesses)</param>
public iBot(int PID)
{
// Process-Objekt erstellen
proc = Process.GetProcessById(PID);
// Fenster enumerieren um das iBot Hauptfenster zu finden
EnumWindows ew = new EnumWindows();
ew.GetWindows();
// Die Liste der Fenster durchsuchen
foreach (EnumWindowsItem item in ew.Items)
{
// Und jedes Fenster, das iB0t] im Titel hat bearbeiten
if (item.Text.Contains("iB0t]"))
{
// Überprüfen ob die WindowThreadId in der ThreadListe des Prozesses vorkommt.
foreach (ProcessThread thr in proc.Threads)
{
if ((int)item.WndThreadId == thr.Id)
{ // Wenn ja
// EnumWindowsItem speichern
eWindowsItem = item;
break;
}
}
}
if (eWindowsItem != null)
break;
}
}
#endregion
#region Construct by Process
/// <summary>
/// Constructor-Methode
/// </summary>
/// <param name="iProc">Prozess-Klasse des iBot-Prozesses</param>
public iBot(Process iProc)
{
// Process-Objekt erstellen
proc = iProc;
// Fenster enumerieren um das iBot Hauptfenster zu finden
EnumWindows ew = new EnumWindows();
ew.GetWindows();
// Die Liste der Fenster durchsuchen
foreach (EnumWindowsItem item in ew.Items)
{
// Und jedes Fenster, das iB0t] im Titel hat bearbeiten
if (item.Text.Contains("iB0t]"))
{
// Überprüfen ob die WindowThreadId in der ThreadListe des Prozesses vorkommt.
foreach (ProcessThread thr in proc.Threads)
{
if ((int)item.WndThreadId == thr.Id)
{ // Wenn ja
// EnumWindowsItem speichern
eWindowsItem = item;
break;
}
}
}
if (eWindowsItem != null)
break;
}
}
#endregion
#endregion
}
}
[/cs]
Die EnumWindows-Klasse ist hier:
http://www.koders.com/csharp/f…921220968210292B4D9B.aspx
Ich habe sie um zwei Funktionen erweitert.
UnManagedMethods:
[cs] [DllImport("user32", CharSet = CharSet.Auto)]
public extern static IntPtr GetWindowThreadProcessId(
IntPtr hWnd,
IntPtr ProcessId);
[DllImport("user32.dll", EntryPoint = "SetWindowText", CharSet = CharSet.Ansi)]
public static extern bool SetWindowText(
IntPtr hWnd,
String strNewWindowName);[/cs]
EnumWindowsItem -> public string Text mit set erweitert:
[cs] set
{
UnManagedMethods.SetWindowText(hWnd, value);
}[/cs]
Und die Eigenschaft WndThreadId hinzugefügt:
[cs]public IntPtr WndThreadId
{
get
{
return(UnManagedMethods.GetWindowThreadProcessId(this.Handle, IntPtr.Zero));
}
}[/cs]
pushedit: Kommt schon ... keiner ne idee? Problem besteht immernoch
Gruß
florian0