» »

kako narediti program ki bere drugi program

kako narediti program ki bere drugi program

perooo25 ::

Živjo,
kako bi naredil program, ki iz drugega programa razbere ali zazna da se je neko polje obarvalo -->naprimer: imam program v katerem je neko polje obarvano belo in ob neki akciji programa se bi to polje obarvalo zeleno, takrat bi drugi program-(katerega želim narediti), to zaznal in bi preko usb-ja (in verjetno kakšnega krmilnika) zagnal motor, ko v prvem programu polje ponovno postane belo (se barva iz zelene spremeni v belo), pa bi ta motorček ugasnil.

p.s.: bistvo je v tem da imam program, katerega sem kupil, in bi ga rad nadgradil, vendar ne morem spreminjati kode programa, kar pomeni da moram narediti svojega, ki bi bral ta program.

vnaprej hvala za pomoč.

LP

WarpedGone ::

Simpl ideja (že sprobana v praksi): delaš srcreen-shote okna in v BMPsliki detektiraš barvo pikslov na nekih koordinatah.
Zbogom in hvala za vse ribe

gendale ::

mrbrdo je parkrat razlagal o teh rečeh (če se prav spomnim), upaj da vidi tvojo temo
seznam zanč moderatorjev in razlogov da so zanč
http://pastebin.com/QiWny5dV
gor je mavrik apple uporabniček (mali možgani in mali penis)

Mavrik ::

Moral boš povedati operacijski sistem in verzijo le-tega.
The truth is rarely pure and never simple.

perooo25 ::

WarpedGone je izjavil:

Simpl ideja (že sprobana v praksi): delaš srcreen-shote okna in v BMPsliki detektiraš barvo pikslov na nekih koordinatah.


super, tud sam sm nekaj razmišljou okoli screenshotov (ker je to okno vedno odprto na maxumum, tako da je to polje vedno na enakem položaju), vendar nisem se mogel spomniti kako narediti naprej.

sedaj bi pa bolj potreboval uslugo, če bi mi lahko kdo vsaj malo napisal kodo, ker sam ravno ne obvladam C#, kar koli drugega pa sploh ne :)

in pa še kakšna ideja glede usb in motorja (ta moj program bi bral 2 polja tako da bi se moral motor, glede na polja vrteti tako:
1. polje: belo - 2. polje zeleno -> motor se vrti v levo
1. polje: zeleno - 2. polje belo -> motor se vrti v desno
1. polje: belo - 2. polje belo -> motor se ne vrti


os: windows 7 32-bit

Zgodovina sprememb…

  • spremenil: perooo25 ()

perooo25 ::

in še screenshot, sedanjega programa

Gandalfar ::

_Dormage_ ::

Za sreenshote v C# je mali miljon primerov.
Ideja je, da slike ne shranjuješ na disk ker so I/O opracije relativno počasne.
Sliko spraviš v objekt v Javi je BufferedImage v C# pa sigurno nekaj podobnega.
V tem objektu je slika predstavljena kot matrika slikovnih točk (pixlov) in vsak pixel je sestavljen iz 4 vrednosti (RGBA)
RGB barvni model upam, da je jasen, če ne pa RGB color model @ Wikipedia
Enkrat ko imaš sliko v objektu je preverjanje trivialno. Malček se sprehajaj po matriki in poglej RGB vrednosti posameznih delov in ugotovi kakšne barve je.

Glede motročkov boš rabil mikrokrmilnik. Svetujem Arduinota!
Arduino se lahko napaja prek USB vmesnika iz katerega lahko napajaš tudi motročke je pa USB po standardu omejen na 5V in 500mA (približki). Na USB vmesniku odpreš serial port http://csharp.simpleserial.com/ in pošiljaš podatke, ki jih bereš z arduinotom (http://arduino.cc/en/Reference/serial).

Če hočeš motroček gnat v obe smeri je to bolj stvar elektrotehnike.
Mislim pa, da lahko rešiš z dvojnim ali zaželjeno trojnim stikalom. Eno stanje za naprej, drugo za nazaj tretje pa za stop.
Lahko poškoduješ motor, če nenadoma zamenjaš smer brez, da bi se motorček prvo ustavil.
To bo najbolje, da uprašaš na forumu za elektrotehniko :))

perooo25 ::

no, motorček in krmilnik sem kupil, vendar se že 2 dni trudim narediti vsaj osnovni programček v c# da bi gnal motorček naprej, nazaj in ga ustavil.

Krmilnik: http://www.pololu.com/catalog/product/1...
Že narejeni programi za "pomoč": http://www.pololu.com/docs/0J40/8

prosim za pomoč, če bo kdo znal to narediti, prav tako pa še glede skeniranja pixlov, mi ni njajbolj jasno kako bi naredil, sem gledal po internetu, vendar ne vem kako narediti

Prosim za pomoč.

Hvala :D

MrBrdo ::

gendale ;)
Tukaj sicer nimam preveč dodati, so bili dobri predlogi - najbolj enostavno bo res s screenshotom...
Poglej si WM_PRINT in WM_PRINTCLIENT (googlaj). Prednost tega je da deluje tudi če je okno pomanjšano ali na zaslonu ni vidno. Sicer je to odvisno od programa, včasih deluje včasih ne. Če ti to ne bo delalo moraš uporabit bitblt. Te zadeve so vse C++, za C# boš moral uporabit P/Invoke. Lahko tudi pogooglaš screenshot C#, vendar v tem primeru mora bit okno in gumb vidno na zaslonu. V tem primeru lahko uporabiš FindWindow/FindWindowEx in GetWindowRect da dobiš koordinate okna na zaslonu. Malo se boš moral poigrat. Velika verjetnost obstaja, da boš moral uporabiti kakšen WinAPIje kar pomeni P/Invoke ali C++ DLL ki ga kličeš iz C#. Najlažje ti bo verjetno če najprej napišeš preprosto konzolno C++ aplikacijo in tam preveriš delovanje (npr. da izpiše Zeleno ali NeZeleno...). Vsekakor bo to lažje izvest v C++ kot v C#.
Verjetno ti ni vse jasno kar sem napisal ampak na žalost nimam časa da bi ti bolj podrobno razložil. Za začetek ti bo najlažje če pogooglaš C# screenshot to Bitmap. Ko imaš Bitmap objekt lahko kličeš GetPixel se mi zdi, ki ti vrne Color, iz Color lahko preveriš .R, .G, .B, in tako vidiš ali je ta pixel zelen ali bel (recimo narediš G > 128, R < 128, B < 128, tako imaš veliko tolerance).
MrBrdo

Zgodovina sprememb…

  • spremenilo: MrBrdo ()

zigi ::

Lahko pa si v C# spišeš samo enostaven console program, ki ti motorček zažene oziroma ustavi glede na podane parametre, recimo:
'MyApp.exe -Start' (zagon)
'MyApp.exe -Stop' (ustavitev)

Potem pa uporabiš AutoIt, napišeš enostavno skripto, ki preko funkcije PixelGetColor dobi barvo gumba in zažene tvoj program z ustreznim parametrom.

Just an idea :)

perooo25 ::

aha, hehe, sem dosti gledal po internetu, vendar moje znanje programiranja še ne zadošča temu, da bi sam naredil program, tako da bi bil zelo vesel, če mi kdo naredi program, vsaj za branje barve pixla (tako da jaz spremenim le koordinate), naprej na motorček pa ga bom poizkusil sam vezati

:D

c3p0 ::

Če je okolje Windows, lahko napišeš enostavno AHK (AutoHotKey) skripto. Jezik je precej enostaven. Nekako te klice rabiš:

hdc_buffer := DllCall("gdi32.dll\CreateCompatibleDC", UInt, hdc_frame)
hbm_buffer := DllCall("gdi32.dll\CreateCompatibleBitmap", UInt,hdc_frame, Int,A_ScreenWidth, Int,A_ScreenHeight)
DllCall( "gdi32.dll\SelectObject", UInt,hdc_buffer, UInt,hbm_buffer)
DllCall( "PrintWindow", UInt , t_id , UInt , hdc_buffer , UInt , 0 )
pix := DllCall("GetPixel", UInt, hdc_buffer, Int, pixel_x , Int, pixel_y)

Se najdejo celotni primeri. Deluje tudi ob pomanjšanem oknu, kar ne velja za vse primere.
Sam AHK uporabljam za avtomatiko nekih drugih programov in deluje odlično.

MrBrdo ::

AutoIt je že boljše potem. Sicer ne vidim prednosti tega tvojega AutoHotKey, ker samo kličeš WinAPIje z ogabno sintakso, zadevo bi lahko enako napisal v Cju le da bi bila koda veliko lepša in verjetno še krajša... Pravzaprav bi še v C# lepše prišlo, samo iz pinvoke.net skopiraš definicije za omenjene WinAPIje in jih kličeš iz C#.
MrBrdo

c3p0 ::

Kakorkoli, v AHK sem zadevo razvil v slabi urci brez predznanja o Win API. Resourceov praktično ne žre, čeprav skenira do 10 oken 10x na sekundo.
Lepoto kode pa prihranimo za drugo temo, kolikor vidim AutoIt ni nič boljši, kar predlagaš se lahko izvede z obema. Če pišeš v C, dodaš še loop, čemu bi sploh mešal zraven kaj druga.

http://www.autoitscript.com/autoit3/doc... - jaka lepota

perooo25 ::

hehe, bom poizkusil kaj preštudirati, vendar zaenkrat nimam pojma kaj bi to bilo, :) pomoč še vedno prav pride ;)

MrBrdo ::

Sago:
brez predznanja o Win API

Od tvojih 5 vrstic čisto vsaka vsebuje WinAPI. In kot sem rekel, v Cju bi bila koda skoraj povsem enaka le manj kompleksna. Tako da nima prav veliko smisla uporabiti ta AHK, vsaj v tem primeru nimaš popolnoma nič od njega, razen odvečen dependency.
MrBrdo

perooo25 ::

in kako bi izgledala ta koda v naprimer c# ? ;)

Zgodovina sprememb…

  • spremenil: perooo25 ()

_Dormage_ ::

MrBrdo ::

perooo25 je izjavil:

in kako bi izgledala ta koda v naprimer c# ? ;)

mislim da je dovolj če dam primer za eno vrstico iz AHK. za ostale je enak postopek...
hdc_buffer := DllCall("gdi32.dll\CreateCompatibleDC", UInt, hdc_frame)

tole skopiraš iz pinvoke.net in vržeš nekam v class
    [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleDC")]
    public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

v metodi kjer želiš to uporabit enako kot je zgornji primer v AHK pa:
IntPtr hdc = CreateCompatibleDC(IntPtr.Zero);

V tem primeru pomeni IntPtr.Zero cel ekran, lahko pa mu daš namesto tega rezultat od APIja FindWindow, če želiš samo neko konkretno okno. Glede tega APIja poglej v dokumentacijo, ni nič posebej težkega.
Pri uporabi APIjev pa pomaga Microsoftova dokumentacija: http://msdn.microsoft.com/en-us/library...

Še primer za isto stvar v C++ (še najbolj enostavno):
#include <Windows.h>
...
HDC hdc = CreateCompatibleDC(NULL);


Tudi primer ki ga je dal Dormage za C# bi moral biti vredu.
MrBrdo

Zgodovina sprememb…

  • spremenilo: MrBrdo ()

_Dormage_ ::

Ko sem podobno delal v javi je bil problem, da je zajem iger oziroma directX aplikacij bila ena velika črnina.
OpenGl je bil kul. A bo tvoj primer zajemal tudi igre?

perooo25 ::

ne, zajema navaden program.

_Dormage_ ::

Kaj pa je navaden program?
Ker sistemski print screen ujame tudi vsebino igre.
Glede na to, da zgornji primer klice neke dllje sem upal, da klice sistemski klic za dobit print sreen.
A se, da na enostaven način naredit print sreen, ki bo zajemal vse ?

perooo25 ::

ja, jaz mislim narediti program ki bi preverjal lahko tudi samo 2 pixla v programu, in sicer ce se en pixel obarva iz bele v zeleno da se naredi dogodek "X", če pa se obarva drugi iz bele v zeleno pa se naredi dogodek "Y", če sta oba bela je dogodek "nič" - se ne zgodi nič.

p.s.: lahko ti po ZS pošljem link od demo programa, da bi mi pomagal narediti to kodo ;)

LP

MrBrdo ::

_Dormage_ je izjavil:

Ko sem podobno delal v javi je bil problem, da je zajem iger oziroma directX aplikacij bila ena velika črnina.
OpenGl je bil kul. A bo tvoj primer zajemal tudi igre?

Za DirectX je vse skupaj malo bolj komplicirano... WM_PRINT tukaj nebi nič pomagal. Malo poenostavi se pri Windows 7 (mislim da tudi Vista) kjer pravzaprav vse skupaj laufa v DirectX in je zajemanje npr. zaslona z DirectX oknom bolj enostavno.
MrBrdo

perooo25 ::

wooo, bolj ko gledam te kode manj mi je jasno, ali je res potrebno toliko kode za en navaden program ki bere le 2 pixla v drugem programu, in javi če kateri od pixlov spremeni barvo ?

MrBrdo ::

Ja. Mogoče programiranje ni zate, če se ti zdi 100 al koliko vrstic tako veliko ;)
MrBrdo

perooo25 ::

če mi nekdo izdela program, pa da vidim teh 100 vrstic mi bo vrjetn takoj vse jasn ;) hehe (tako kot ponavad)

MrBrdo ::

Si pa res pravi programer ;)
MrBrdo

perooo25 ::

Živjo imam problem pri kodi, (verjetno je pri threadu), program mi yablokira pri if stavku ko najde iskano barvo

koda:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{

    [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
    public static extern int BitBlt(IntPtr hDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);


    Thread t;
    Thread f;
   
    int xL, yL;
    int xD, yD;

    public Form1()
    {
        InitializeComponent();
    }

   

    private void button1_Click(object sender, EventArgs e)
{
       xL = 500;
       yL = 120;
       xD = 650;
       yD = 120;
        t = new Thread(updateL);
        t.Start();
        f = new Thread(updateD);
        f.Start();
    }
    public void updateL()
    {
        Bitmap screenCopy = new Bitmap(1, 1);
        using (Graphics gdest = Graphics.FromImage(screenCopy))
        {
            while (true)
            {
                //g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(256, 256));
                using (Graphics gsrc = Graphics.FromHwnd(IntPtr.Zero))
                {
                    IntPtr hSrcDC = gsrc.GetHdc();
                    IntPtr hDC = gdest.GetHdc();
                    int retvalL = BitBlt(hDC, 0, 0, 1, 1, hSrcDC, xL, yL, (int)CopyPixelOperation.SourceCopy);
                    gdest.ReleaseHdc();
                    gsrc.ReleaseHdc();
                }
                Color cL = Color.FromArgb(screenCopy.GetPixel(0, 0).ToArgb());
               label1.ForeColor = cL;
                  
                if (cL.G == 255 && cL.B == 1 && cL.A == 255)
                   {
//tu nastane problem !!
                       if (label2.Visible = false)
                        {
                            if (label3.Visible = true)
                            {
                             label3.Visible = false;
                             label2.Visible = true;
                            }
                        }
                   }  
               }  
        }
    }
    public void updateD()
    {
        Bitmap screenCopy = new Bitmap(1, 1);
        using (Graphics gdest = Graphics.FromImage(screenCopy))
        {
            while (true)
            {   
                //g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(256, 256));
                using (Graphics gsrc = Graphics.FromHwnd(IntPtr.Zero))
                {
                    IntPtr hSrcDC = gsrc.GetHdc();
                    IntPtr hDC = gdest.GetHdc();
                    int retvalL = BitBlt(hDC, 0, 0, 1, 1, hSrcDC, xD, yD, (int)CopyPixelOperation.SourceCopy);
                    gdest.ReleaseHdc();
                    gsrc.ReleaseHdc();
                }
                Color cD = Color.FromArgb(screenCopy.GetPixel(0, 0).ToArgb());
                label4.ForeColor = cD;
                    if (cD.G == 255 && cD.B == 1 && cD.A == 255)
                    {
//tu nastane problem!!
                        if (label3.Visible = false)
                        {
                            if (label2.Visible = true)
                            {
                                label3.Visible = false;
                                label2.Visible = true;
                            }
                        }                        
                    }       
            }
        }

    }
    private void button2_Click(object sender, EventArgs e)
    {
        t.Abort();
        f.Abort();   
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        label5.Text = "burek";
        label2.Visible = true;
    }
    private void button3_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }
    }
    }

hvala za pomoč!! (lahko pošljem tudi program)

še screenshot :

Zgodovina sprememb…

  • spremenil: perooo25 ()

darkolord ::

zakaj pa imaš tisti while(true) ?

Mavrik ::

Saj ti zelo jasno piše: label2 probaš spreminjati na drugem threadu, kot je bil ustvarjen - vse spremembe GUIja moraš narediti na UI threadu, ne pa na dodatnih threadih kot jih ti ustvarjaš.
The truth is rarely pure and never simple.

perooo25 ::

Ali je ta while problem? ;)

Zgodovina sprememb…

  • spremenil: perooo25 ()

darkolord ::

Oboje je problem. Kaj točno bi rad naredil?

Zgodovina sprememb…

  • spremenilo: darkolord ()

Mavrik ::

Kaj točno pa ma while s tem da spreminjaš UI element z ne-UI threada? A si sploh prebral kaj sem napisal in kaj ti je exception napisal?!
The truth is rarely pure and never simple.

perooo25 ::

darkolord je izjavil:

Oboje je problem. Kaj točno bi rad naredil?


rad bi da program bere 2 pixla, in če je 1. pixel določene barve se prikaže label2, enako velja za 2. pixel le da se prikaže label3, nikoli pa nista oba pixla naenkrat enake barve




Mavrik je izjavil:

Kaj točno pa ma while s tem da spreminjaš UI element z ne-UI threada? A si sploh prebral kaj sem napisal in kaj ti je exception napisal?!


prebal ja, vendar ne znam prav dobro delati s threadi in mi je ratal problem, glede whila pa nevem, ker sem ta del kode skopiral iz neta

Zgodovina sprememb…

  • spremenil: perooo25 ()

darkolord ::

Prvi problem je to s threadi. Tisti del kode, ki se dotika UI, moraš zalavfati v tistem threadu, v katerem laufa UI.

Na hitrco lahko nekako takole:
this.Invoke((Action)(() =>
{
   // tvoji if stavki pa to
}
));


Drugi problem je, da imaš if stavke narobe napisane. Pri preverjanju enakosti moraš uporabiti dvojni enačaj:

if (label3.Visible == false) 


Tretji problem je pa to, da ti bo koda požrla precej procesorja, ker to počneš v neskončni zanki brez Sleep() in to, da se zanka nikoli na zaključi - tudi ko najde pravo barvo, bo še vedno delalo naprej.

krneki0001 ::

S podobno zadevo sem se sam igral, samo da sem imel en program na ekranu, drugio pa je v ozadju delal s kamero usmerjeno na monitor. Ko se je na ekranu kaj spremenilo - pri meni se je pokazala QR koda vsake toliko časa, je program s kamero to zaznal in si zapisal, kaj je bilo zapisano v qr kodi. Uporabil sem pa Emgu.CV knjižnjico, ki je zastonj.
Asrock X99 Extreme 4 | Intel E5-2683V4 ES | 64GB DDR4 2400MHz ECC |
Samsung 250GB M.2 | Asus 1070 TI | 850W Antec | LC Tank Buster

perooo25 ::

Ok, hvala za odgovor, ja glede pricesorja vem, vendar mi bo morala aplikacija preverjati barvo ves cas do prekinitve dela s programom(to je tudi namen programa), ce vseeno obstaja kaksna moznost da ne pozira toliko procesorja ob istem delovanju aplikacije pa povejte ;)

imagodei ::

Emm, ne moreš dati zadeve v kak timer, ki se proži na, i dunno, 100 ms?
- Hoc est qui sumus -

MrBrdo ::

al pa thread in sleep metoda, ce hoces "grše" narest
MrBrdo

perooo25 ::

darkolord je izjavil:

Prvi problem je to s threadi. Tisti del kode, ki se dotika UI, moraš zalavfati v tistem threadu, v katerem laufa UI.

Na hitrco lahko nekako takole:

this.Invoke((Action)(() =>
{
// tvoji if stavki pa to
}
));


Drugi problem je, da imaš if stavke narobe napisane. Pri preverjanju enakosti moraš uporabiti dvojni enačaj:

if (label3.Visible == false) 


Tretji problem je pa to, da ti bo koda požrla precej procesorja, ker to počneš v neskončni zanki brez Sleep() in to, da se zanka nikoli na zaključi - tudi ko najde pravo barvo, bo še vedno delalo naprej.


Kljub temu da sem vstavil ta stavek this.invoke... Mi if stavki se vedno ne delujejo :( while pa mora biti da mi program vedo osvezuje

darkolord ::

Ti javi še vedno isto napako?

perooo25 ::

Ne, napake ne javi vec, vendar labelov se vedno ne prikazuje in ne skriva, kot da if stavki nebi delovali

MrBrdo ::

Če imaš namen kdaj resno programirat potem se boš moral navadit kdaj tudi sam kaj probat in debugirat...
MrBrdo

Spura ::

To je pa dost zoprno da ti ne pusti iz drugih threadov spreminjat stvari.
Emm, ne moreš dati zadeve v kak timer, ki se proži na, i dunno, 100 ms?

In kako timer resi problem dostopov iz drugega threada?

imagodei ::

Se nisem ubadal s tem; ti pa reši 99% zasedenost jedra, ker bi se preverjanje dogajalo non-stop.
- Hoc est qui sumus -


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[C#] pixel scan z Thread

Oddelek: Programiranje
121057 (839) perooo25
»

Tezava pri instanciranju class-a

Oddelek: Programiranje
61177 (1048) KernelPanic
»

C# Pomoč

Oddelek: Programiranje
131303 (1128) jizzer
»

uporaba C++ unmanaged kode v C#.NET projektu

Oddelek: Programiranje
111821 (1544) krho
»

C++ programirane v Open GL oz. Direct x

Oddelek: Programiranje
242865 (2136) Vesoljc

Več podobnih tem