Morjens.
Miten voin kaapata kaiken tekstin toisen ohjelman ikkunasta? Onko mahdollista saada tietoon vielä tekstin väriä ja sijaintia ikkunassa?
Kerro millaista ratkaisua olet yrittänyt ja mihin on tyssännyt?
Mihin tarvitset tällaista?
Innostuin pitkästä aikaa nettipokerista ja ajatelin kokeilla tehdä eräänlaisen apuohjelman peliin. Pokeribotin koodaaminen on aina ollut haaveena, mutta ajattelin aloittaa homman tällaisella pienellä apuohjelmalla joka laskee mm potti- ja vetokertoimia ynnä pitää yllä pientä tilastoa.
Itse laskemisen ja tilastot pystyn luullakseni toteuttamaan helposti, mutta ongelma on pelitapahtumien lukeminen pelistä.
Käsittääkseni ainoa tapa selvittää pelin kulkua on näytön lukeminen. Softa kyllä ylläpitää logia aiemmista peleistä, mutta jos haluan reaaliaikaisen apuohjelman ei niillä tiedoilla tee oikeastaan mitään.
Jotain olen "kokeillut", mutta kun asia on uusi, outo ja kieli englanti, niin ajattelin kysyä apua suomalaisilta guruilta.
http://bytes.com/topic/visual-basic-net/answers/363935-extracting-text-another-application
http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/02a67f3a-4a26-4d9a-9c67-0fdff1428a66
http://www.codingthewheel.com/archives/how-i-built-a-working-poker-bot
Pokerisivusto on Pacific poker. Ja kuvia peli-ikkunasta löytää helposti Google kuvahaulla.
Onko peli java, flash vai mikä? Luultavasti joudut tekemään OCR:än tai sitten jonkin, joka osaa muistista lukea.. Vaikeaa joka tapauksessa.
Ruudulta lukeminen on kyllä vihoviimeinen idea. Yleispätevin ja usein helpoin ratkaisu on tehdä pelin verkkoprotokollan kanssa yhteensopiva oma peliklientti, joka siis keskustelee suoraan pelipalvelimen kanssa ja korvaa täysin alkuperäisen pelin. Jos peli pyörii suoraan selaimessa (HTML ja JS), vaihtoehtona on myös tehdä omat "laajennokset" JavaScriptilla ja lisätä ne sivulle esimerkiksi Firefoxissa Greasemonkey-lisäosalla, jolloin ne voivat lukea tietoja suoraan sivun lähdekoodista tai sivun JavaScriptin muista osista.
Joo nuo kortit on aika helppo tunnistaa vaikka GetPixelillä, Mutta en tiedä tuosta tekstikentästä. KOkeile GetText APIa,, se luultavasti toimii jos peli on html js pohjainen.
EDIT: jaa metabolix ehti jo väliin.. kirjotin tätä muutaman tunnin..
Moi novice!
elikä "Jos peli pyörii suoraan selaimessa" niin voit poimia HTML:stä vaikka näin
Imports System
Public Partial Class MainForm
Public Sub New()
Me.InitializeComponent()
End Sub
Sub WebBrowser1_DocumentCompleted(sender As Object, _
e As WebBrowserDocumentCompletedEventArgs)
Timer1.Interval = 500
Timer1.Enabled = True
Timer1.Start
End Sub
Sub MainForm_Shown(sender As Object, e As EventArgs)
WebBrowser1.Url = _
New Uri("https://www.ohjelmointiputka.net/morpion/peli.php")
End Sub
Sub Timer1_Tick(sender As Object, e As EventArgs)
Timer1.Stop
Static bodyTag As String
Dim bodyStr As String = WebBrowser1.Document.Body.OuterHtml
If bodyTag <> bodyStr Then
textBox1.Clear
Dim elems As HtmlElementCollection
elems = WebBrowser1.Document.GetElementsByTagName("p")
For i = 0 To elems.Count - 1
Dim elemStr As String = elems.Item(i).InnerHtml.ToString
'testi...
If elemStr.IndexOf("INPUT") = -1 And _
elemStr.IndexOf("A href") = -1 Then
textBox1.Text += elems.Item(i).InnerText _
+ Environment.NewLine
End if
Next
End If
bodyTag = bodyStr
Timer1.Start
End Sub
End ClassNea: Enpä usko että toi hyödyttää suurelti kun kyseessä on Flash-peli.
novice: protip: Sitä englantia kannattaa oikeasti opetella sillä kaikki hyvä matsku on englanniksi.
Itse olen koodannut jotain samanlaista C:llä flash-peliä varten, ja todennut viritelmäni toimivaksi. Käytän koodissani IWebBrowser2-interfacea, jolla kirjaudutaan peliin ja siirrytään pelisivulle. Pelisivulla tapahtuu flash-pelin (.swf-tiedosto) lataaminen ja pelaaminen. Jotta pystyn seuraamaan pelin tapahtumia, olen hookannut oman prosessin connect()-, send()- ja recv()-funktiot ws2_32.dll:stä. connnect-hookilla saan selville soketin, jonka kautta tapahtuu peliklientin keskustelu (tiedän että peli yrittää yhdistää porttiin 30000). Sen jälkeen vain seuraan sen soketin kautta kulkevaa nettiliikennettä ja reagoin siihen haluamallani tavalla.
Tämä on varmasti monelle vaikea lähestymistapa ongelmaan, mutta kohtuullisen vakaa ja pienitöinen verrattuna kokonaan oman peliklientin kirjoittamiseen. Jotain mahdollisia ongelmia kuitenkin on. Nettiliikenne voi olla salattu, pelin nettiprotokolla tulee ymmärtää, sekä kun peliä päivitetään se voi vaatia myös ohjelmasi päivittämistä. Nämä kaikki ongelmat on kuitenkin olemassa myös silloin, kun koodataan kokonaan oma klientti.
Et ole edes kertonut, toimiiko pelisi flashilla vai millä. Näytöltä lukeminen voi toimia ihan hyvin, jos se toteutetaan oikein. Kyse on pelkästään pokeripelistä, joten pelkkien korttien tunnistaminen ei pitäisi olla kohtuuttoman vaikeaa. Ei myöskään olisi kovin vaikeaa pyytää käyttäjää syöttämään ohjelmaan jaetut kortit, jolloin ohjelma toimisi mahdollisesti myös muiden samanlaisten pokeripelien kanssa.
edit. Jaahas, pacific poker kyseessä. Näyttäisi siltä ettei toimi flashilla, Toi mun ehdottama tapa toimii edelleenkin, joskin sen toteuttaminen on hieman vaikeampaa, koska funktiot tulee hookata etäprosessista. Kun kyseessä näyttää olevan tavallinen binäärisovellushärveli, niin yksi vaihtoehto olisi memory editorilla (cheat engine) selvittää missä kohtaa muistia tiedot korteista säilytetään ja lukea ne sieltä. Voi olla vaikeaa jos ei ole ennen säätänyt tällaisia juttuja. Se olisi helppo ja varma tapa, mutta sitäkin joutuisi päivittelemään kun peliä päivitetään.
Peli ei pyöri selaimessa vaan on käsittääkseni ihan tavallinen koneelle asennettava windows sovellus (en kyllä ole yhtään varma).
Itse korttien lukeminen näytöltä pikselitarkistusena ei ole ongelma, vaan muiden pelaajien toimintojen selvittäminen. Esim. ketä on pelissä mukana, paljonko pelaajalla on rahaa, maksoiko/luovuttiko/vai korottiko pelaaja, paljonko potissa on rahaa, yms.
Tuli yllättävä meno en ehtinyt kirjoittaa viestiä valmiiksi asti...
Yritin seuraavaa koodia tekstin kaappaamiseen:
'Formille 2 buttonia, label ja 2 listboxia
Public Class Form1
Dim WindowsStuff As Class1 = New Class1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ListBox1.Items.Clear()
WindowsStuff.GetActiveWindows()
For Each AW In WindowsStuff.ActiveWindowList
ListBox1.Items.Add(AW.ToString & vbTab & WindowsStuff.GetWindowsText(AW))
Next
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
ListBox2.Items.Clear()
Dim SelectedhWnd As IntPtr
If ListBox1.SelectedIndex <> -1 Then
SelectedHwnd = WindowsStuff.ActiveWindowList(ListBox1.SelectedIndex)
Label2.Text = WindowsStuff.GetWindowsText(SelectedHwnd)
Else
Exit Sub
End If
WindowsStuff.GetChildWindows(SelectedhWnd)
For Each item In WindowsStuff.ChildWindowList
ListBox2.Items.Add(item.ToString & vbTab & WindowsStuff.GetWindowsText(item))
Next
End Sub
End ClassImports System.Runtime.InteropServices
Public Class Class1
Public Declare Function EnumChildWindows Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal adress As CallBack, ByVal lParam As Integer) As Boolean
Public Declare Function EnumWindows Lib "user32.dll" (ByVal Adress As CallBack, ByVal lparam As Integer) As Integer
Public Delegate Function CallBack(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
Private Const WM_GETTEXT As Integer = &HD
Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As String) As IntPtr
Public Declare Function IsWindowVisible Lib "user32.dll" (ByVal hWnd As IntPtr) As Boolean
Public ChildWindowList As List(Of IntPtr)
Public ActiveWindowList As List(Of IntPtr)
Public Function GetChildWindows(ByVal ParentHandle As IntPtr)
ChildWindowList = New List(Of IntPtr)
Dim ListHandle As GCHandle = GCHandle.Alloc(ChildWindowList)
EnumChildWindows(ParentHandle, AddressOf EnumChildWindowList, GCHandle.ToIntPtr(ListHandle))
Return ChildWindowList.ToArray
End Function
Public Function GetActiveWindows()
ActiveWindowList = New List(Of IntPtr)
EnumWindows(AddressOf EnumActiveWindowList, 0)
Return ActiveWindowList.ToArray
End Function
Private Shared Function EnumChildWindowList(ByVal hWnd As IntPtr, ByVal lParam As integer) As Boolean
Dim ChildWindowList As List(Of IntPtr) = GCHandle.FromIntPtr(lParam).Target
ChildWindowList.Add(hWnd)
Return True
End Function
Private Function EnumActiveWindowList(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
If IsWindowVisible(hWnd) Then
ActiveWindowList.Add(hWnd)
End If
Return True
End Function
Public Function GetWindowsText(ByVal hWnd As IntPtr)
Dim Name As String = Space(100)
Dim NumText As Integer = SendMessage(hWnd, WM_GETTEXT, 50, Name)
Return Trim(Name)
End Function
End ClassEn täysin ymmärrä mitä yllä olevassa koodissa tapahtuu, mutta pokeripeli-ikkunasta se ei löydä kuin kuusi childwindowia joista vain yhdestä (chatruutu) löytyy tekstiä.
Peli-ikkunassa kuitenkin on tekstiä, miten sen saisi kaapattua?
Deffi kirjoitti:
...niin yksi vaihtoehto olisi memory editorilla (cheat engine) selvittää missä kohtaa muistia tiedot korteista säilytetään ja lukea ne sieltä. Voi olla vaikeaa jos ei ole ennen säätänyt tällaisia juttuja.Se olisi helppo ja varma tapa, mutta sitäkin joutuisi päivittelemään kun peliä päivitetään.
Olipa tapa mikä hyvänsä, joutuu sitä luultavasti aina päivittämään pelipäivityksen jälkeen.
novice kirjoitti:
Softa kyllä ylläpitää logia aiemmista peleistä...
Voisiko tuon login tulevan lisäyksen jotenkin kaapata muistista, tai jostain...?
Deffi kirjoitti:
Kun kyseessä näyttää olevan tavallinen binäärisovellushärveli, niin yksi vaihtoehto olisi memory editorilla (cheat engine) selvittää missä kohtaa muistia tiedot korteista säilytetään ja lukea ne sieltä.
Cheat engine! Sillähän nuo tekstit näytti löytyvän (nopeasti vain kokeilin). Pitääpä alkaa reenaileen tuota muistista lukemista....
Saatko Spy++:lla tarkasteltua ikkunan tekstejä? Jos saat niin APEja hyödyntämällä kaappaus kyllä onnistuu..
Epäilen tosin suuresti jos kyseessä on flash peli.
JussiR kirjoitti:
Saatko Spy++:lla tarkasteltua ikkunan tekstejä? Jos saat niin APEja hyödyntämällä kaappaus kyllä onnistuu..
Epäilen tosin suuresti jos kyseessä on flash peli.
WinSpy lienee samankaltainen ohjelma. löydän sillä kyllä jakajan chat-ruudun, mutta en muuta.
Tyhmä kysymys; Mistä tietää onko peli flash tai jotain muuta?
novice kirjoitti:
Tyhmä kysymys; Mistä tietää onko peli flash tai jotain muuta?
Paina pelin päällä hiiren oikeaa nappia ja katso onko siinä menussa kohta "About Abobe Flash Player" tai muuta Flashiin viittaavaa.
Morjens taas novice!
Mikäli mielenkiintoa vielä riittää niin tässä esimerkki-viritelmä,
joka hyödyntää Local Shared Object eli flash cookies kamaa...
Imports System
Imports System.IO
Imports mshtml
Public Partial Class MainForm
Private basePath As String = String.Empty
Private sourcePath As String = String.Empty
Private tempPath As String = String.Empty
Public Sub New()
Me.InitializeComponent()
End Sub
Sub MainForm_Load(sender As Object, e As EventArgs)
If CheckInstances(Me.Text) Then
Me.Dispose(): End
End If
End Sub
Sub WebBrowser1_DocumentCompleted(sender As Object, _
e As WebBrowserDocumentCompletedEventArgs)
Timer1.Interval = 500: Timer1.Enabled = True: Timer1.Start
End Sub
Sub MainForm_Shown(sender As Object, e As EventArgs)
WebBrowser1.Url = _
New Uri("http://content.funny-games.biz/governor-of-poker-2.swf")
End Sub
Sub Timer1_Tick(sender As Object, e As EventArgs)
If webBrowser1.ReadyState <> 4 Then
Exit Sub
End If
Application.DoEvents
Timer1.Stop
Dim CurrentDocument As MSHTML.IHTMLDocument2 = _
CType(WebBrowser1.Document.DomDocument, IHTMLDocument2)
Dim embeds As IHTMLElementCollection = CurrentDocument.embeds
If embeds.length > 0 Then
If basePath = String.Empty Then
Dim AppDataPath As String = Environment.GetFolderPath( _
Environment.SpecialFolder.ApplicationData)
AppDataPath += _
"\Macromedia\Flash Player\#SharedObjects\33MMP4KX\"
Dim sourceInfo As New DirectoryInfo(AppDataPath)
For Each subDir As DirectoryInfo In sourceInfo.GetDirectories
If subDir.Name.IndexOf(WebBrowser1.Url.Host) > -1 Then
'Käytä kerrallaan vain yhtä pelaajaprofiilia...
'Mikäli luot uuden profiilin niin muista poistaa
'flas-pelin listalta mahdollinen aiempi profiili.
Dim files() As FileInfo = _
subDir.GetFiles("Governor_of_Poker2_v100_demo_*")
If files.length > 0 Then
sourcePath = subDir.FullName + _
"\" + files(0).ToString
tempPath = Environment.GetFolderPath( _
Environment.SpecialFolder.Desktop)
tempPath += "\" + files(0).ToString
End if: Exit For
End If
Next
sourceInfo = Nothing: AppDataPath = Nothing
End If
If sourcePath <> String.Empty Then
FileCopy(sourcePath,tempPath)
Do While Dir(tempPath) = ""
Application.DoEvents: Loop
Dim strFile As String
Dim MyChar As Char() = CType("pokerGame:", Char())
FileOpen(1, tempPath, OpenMode.Input, OpenAccess.Read)
strFile = InputString(1, CType(LOF(1), Integer))
FileClose(1): Dim pos As Integer = _
strFile.IndexOf("pokerGame:")
'Testi (tutki kamaa ja väännä itse oma parseri)...
Try
textBox1.Text = _
strFile.Substring(pos, strFile.Length - pos)
Catch ex As Exeption
sourcePath = String.Empty
End Try
Kill(tempPath): strFile = Nothing
End If
End If
Timer1.Start
End Sub
Private Function CheckInstances(ByVal AppName As String) As Boolean
Dim MyProcess As Process() = _
Process.GetProcessesByName(AppName)
Dim IsAllReadyRunnig As Boolean
If Not MyProcess Is Nothing Then
If MyProcess.Length > 1 Then
IsAllReadyRunnig = True
Else
IsAllReadyRunnig = False
End If
End If
MyProcess = Nothing
Return IsAllReadyRunnig
End Function
Sub MainForm_FormClosing(sender As Object, e As FormClosingEventArgs)
Try
Timer1.Stop
Catch ex As Exception
End Try
Timer1.Enabled = False
Me.Dispose()
End Sub
Sub MainForm_FormClosed(sender As Object, e As FormClosedEventArgs)
End
End Sub
End Classmanne kirjoitti:
Itsekin olen kiinnostunut tästä muistista lukemisesta, mutta ainakin omissa peleissä nuo tietojen sijainnit muistissa vaihtuvat jokaisella pelin käynnistyskerralla. Onko tähän mitään muuta ratkaisua kuin skannata muisti joka kerralla uudestaan?
Kutsutaan DMA:ksi (dynamic memory allocation) ja tämän kiertämiseksi on pari tapaa. Voit etsiä osoittimen joka osoittaa haluaamaasi tietoon. Tietosi voi olla esimerkiksi osa jotain luokkaa/struktuuria, jolloin osoitin ei osoita suoraan haluaamaasi kohtaan, vaan struktin alkuun. Toivon mukaan sitten kun löydät osoittimen, niin se säilytetään aina samassa kohtaa muistia (vaikka peli käynnistettäisiin uudelleen). Sitten pääset haluamaasi tietoon käsiksi lukemalla ensiksi osoittimen arvon ja muokkaamalla osoittimen osoittamaa kohtaa. Joo...
Käyttämällä vaikka Cheat Engineen sisäänrakennettua debuggeria saat selville, missä kohtaa muistia arvoasi käsitellään. Tästä voit tutkia (jos osaat assemblyä) kuinka peli pääsee käsiksi tietoosi, ja käyttää itse samaa tapaa. Toinen vaihtoehto on käyttää code injectioniksi kutsuttua tapaa. Kun tiedät missä arvoasi käsitellään, voit muokata sitä kohtaa ohjelmasta haluamaksesi. Yleensä kirjotetaan hyppy-käsky johonkin omaan pätkään koodia, mikä sitten tekee jotain taikatemppuja. Vaatii jonkinlaista ymmärrystä assemblystä tämäkin.
Jostain syystä hyvien tutoriaalien löytäminen aiheesta (defeating DMA) on nykyään vaikeaa. Kymmenen vuotta sitten gamehacking-skene vielä kukoisti ;-( Cheat Enginen mukana taitaa tulla tutorial.exe, jossa sivutaan näitä ja monia muita hyödyllisiä aiheita.
Morjens taas!
tässä vielä eräs mahdollisuus moisen viritelmän vääntämiseksi...
'EmbedSwfSpy.exe (Väännetty SharpDevelop 4.0 Beta 2:lla)
'Ohjausobjektit:
'Paneeli (panel1), WebBrowser (webBrowser1) & Labelli (label1)
'(WebBrowser-kontrolli paneelin sisälle)
Imports System
Imports System.Runtime.InteropServices
Imports Accessibility '(Accessibility.dll)
Imports AccLayer '(AccLayer.dll) [linkki "http://www.tuubi.net/neansivut/downloads/AccLayer.zip"]löytyy täältä[/linkki]
Imports mshtml '(Microsoft.mshtml.dll saatavilla Office PIAs-paketissa)
'PIAs Office XP:lle [linkki "http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c41bd61e-3060-4f71-a6b4-01feba508e52&DisplayLang=en"]löytyy täältä[/linkki]
'PIAs Office 2003:lle [linkki "http://www.microsoft.com/downloads/en/details.aspx?familyid=3C9A983A-AC14-4125-8BA0-D36D67E0F4AD&displaylang=en"]löytyy täältä[/linkki]
'PIAs Office 2007:lle [linkki "http://www.microsoft.com/downloads/en/details.aspx?FamilyID=59daebaa-bed4-4282-a28c-b864d8bfa513&displaylang=en"]löytyy täältä[/linkki]
'PIAs Office 2010:lle [linkki "http://www.microsoft.com/downloads/en/details.aspx?FamilyID=5d57c998-b630-4f38-afaa-b79747a3da06"]löytyy täältä[/linkki]
Public Partial Class MainForm
Private MyAccObject As IAccessible = Nothing
Private AccNodeObject As IAccessible = Nothing
Public Sub New()
Me.InitializeComponent()
End Sub
Sub MainFormLoad(sender As Object, e As EventArgs)
If CheckInstances(Me.Text) Then
Me.Dispose(): End
End If
Me.AccessibleName = "SwfSpyMainForm"
Me.AccessibleRole = AccessibleRole.Window
Me.webBrowser1.AccessibleName ="BrowserWindow"
Me.webBrowser1.AccessibleRole = AccessibleRole.Window
Me.panel1.AccessibleName = "BrowserPane"
Me.panel1.AccessibleRole = AccessibleRole.Pane
Me.label1.AccessibleName = "DataLabel"
Me.label1.AccessibleRole = AccessibleRole.Window
End Sub
Sub MainFormShown(sender As Object, e As EventArgs)
WebBrowser1.Url = _
New Uri("http://content.funny-games.biz/governor-of-poker-2.swf")
End Sub
Sub WebBrowser1DocumentCompleted(sender As Object, _
e As WebBrowserDocumentCompletedEventArgs)
MyAccObject = Nothing
Dim CurrentDocument As MSHTML.IHTMLDocument2 = _
CType(WebBrowser1.Document.DomDocument, IHTMLDocument2)
Dim embeds As IHTMLElementCollection = CurrentDocument.embeds
If embeds.length > 0 Then
Dim mother As IAccessible = _
Acc.GetAccessibleObjectFromHandle(webBrowser1.Handle)
If mother IsNot Nothing Then
Dim children As Object() = _
Acc.GetAccessibleChildren(mother)
If children.Length > 0 Then
For i As Integer = 0 To children.GetUpperBound(0)
Dim child As IAccessible = _
CType(children(i), IAccessible)
If child.accName = "BrowserWindow" Then
'kotrollien 'solmut' on etsitty:
'AccExplorer32.exe - ohjelmalla [linkki "http://www.expertti.comyr.com/downloads/AccEvent32.zip"]löytyy täältä[/linkki]
Erase children: children = _
Acc.GetAccessibleChildren(child)
child = CType(children(0), IAccessible)
Erase children: children = _
Acc.GetAccessibleChildren(child)
child = CType(children(3), IAccessible)
Erase children: children = _
Acc.GetAccessibleChildren(child)
child = CType(children(0), IAccessible)
Erase children: children = _
Acc.GetAccessibleChildren(child)
child = CType(children(3), IAccessible)
Erase children: children = _
Acc.GetAccessibleChildren(child)
child = CType(children(0), IAccessible)
If child.accName = webBrowser1.Url.ToString Then
AccNodeObject = child: child = Nothing
children = Nothing: mother = Nothing
End If: Exit For
End If
Next i
End If
If AccNodeObject IsNot Nothing Then
timer1.Interval = 250: timer1.Enabled = True: timer1.Start
End If
End If
End If
End Sub
Sub Timer1Tick(sender As Object, e As EventArgs)
If webBrowser1.ReadyState <> 4 Then
Exit Sub
End If
If MyAccObject Is Nothing Then
Dim children As Object() = _
Acc.GetAccessibleChildren(AccNodeObject)
Dim child As IAccessible = Nothing
child = CType(children(0), IAccessible)
Erase children: children = _
Acc.GetAccessibleChildren(child)
child = CType(children(0), IAccessible)
Erase children: children = _
Acc.GetAccessibleChildren(child)
MyAccObject = CType(children(3), IAccessible)
AccNodeObject = Nothing
Else
Dim MyChildren As Object() = _
Acc.GetAccessibleChildren(MyAccObject)
'Dim MyPointer As IntPtr = IntPtr.Zero: label1.Text = ""
For i As Integer = 0 To MyChildren.GetUpperBound(0)
Dim MyChild As IAccessible = Nothing
Try
MyChild = CType(MyChildren(i), IAccessible)
Catch ex As Exception
End Try
If Not MyChild Is Nothing Then
If MyChild.ToString = "System.__ComObject" Then
Try
MyChild.accHitTest(1, 1)
Catch ex As Exception
End Try
Try
'koska tämä tökkii...
'Dim MyProperties As AccPropertySet = _
'New AccPropertySet(MyChild)
'label1.Text = MyProperties.Value
'ja tämä tökkii...
'Dim MyProperties As AccPropertySet = _
'New AccPropertySet(MyChild)
'MyPointer=Marshal.GetIUnknownForObject(MyProperties)
'label1.Text += Marshal.PtrToStringAuto(MyPointer)
'niin päätin lukea suoraan liittymästä...
MyPointer = Marshal.GetIUnknownForObject(MyChild)
label1.Text += Marshal.PtrToStringAuto(MyPointer)
'elikä jos joku keksii keinon parsia dataa tai
'lukea muistia paremmin niin antakoon palaa...
Catch ex As Exception
End Try
End If
End If
Next
If MyPointer <> IntPtr.Zero Then
Dim MyRefCount As Integer = Marshal.Release(MyPointer)
End If
End If
timer1.Start
End Sub
Private Function CheckInstances(ByVal AppName As String) As Boolean
Dim MyProcess As Process() = _
Process.GetProcessesByName(AppName)
Dim IsAllReadyRunnig As Boolean
If Not MyProcess Is Nothing Then
If MyProcess.Length > 1 Then
IsAllReadyRunnig = True
Else
IsAllReadyRunnig = False
End If
End If
MyProcess = Nothing
Return IsAllReadyRunnig
End Function
Sub MainFormFormClosing(sender As Object, e As FormClosingEventArgs)
Try
Timer1.Stop
Catch ex As Exception
End Try
Timer1.Enabled = False
Me.Dispose()
End Sub
Sub MainFormFormClosed(sender As Object, e As FormClosedEventArgs)
End
End Sub
End ClassAihe on jo aika vanha, joten et voi enää vastata siihen.