Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Зайчик
Člen
Avatar
Зайчик:20.1.2013 23:21

Hoj, tak už zase spamuju ale tentokrát už fakt nevím jak dál. Už jsem vyzkoušel snad všechny metody co mě napadly, co jsem vygooglil ale nic nepomohlo a nebo to fungovalo... ale stálo to za prd. Jedná se o listview, který si sám vykresluju. Pomocí funkce, kterou jsem si vytvořil refreshuji listview ze souboru a načítám do něj hodnoty, poté je metoda drawitem vykreslí a přidá obrázek viz. obrázek. Problém je ale v tom že já nějak rozumně potřebuji pingovat servery... ne úplně pingovat ale pomocí TCP spojení zjistit zda jsou online. Pokud ano tak metoda DrawItem u listviewu by měla změnit obrázek na modrý ( on ) pokud je ale server offline změní obrázek na šedý ( offline ). To se mi dokonce i povedlo ale trvalo to moc dlouho a TCP spojení nebylo asynchronní, takže to trvalo věčnost, když byl server offline protože to spojení chvilku pak trvá. ( ani teď to není asynchronní abych nemusel dělat další metodu na změnu DNS na IP ) ale je to udělané přes Thread jak mi poradil sczdavos ( funguje v pohodě ) a tady je :

bool Connecting = false;
        string Server;

        public void TryServerMs(string server, out bool connecting)
        {
            Server = server;
            Thread t = new Thread(TryConnection);
            t.Start();
            connecting = Connecting;
        }

        public void TryConnection()
        {
            TcpClient tcpClient = new TcpClient();
            try
            {
                tcpClient.Connect(Server, 3724);
                Connecting = true;
            }
            catch
            {
                Connecting = false;
            }
        }

Je trošku ošizená... ale funguje tak, jak má. A tady si vykresluju ten listview pomocí metody DrawItem

private void ServerList_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            if (e.Item.Selected == true)
            {
                ServerList.ForeColor = Color.FromArgb(50, 146, 242); // blue text color
                SolidBrush ItemColor = new SolidBrush(Color.FromArgb(51, 51, 51)); // gray ( 51, 51, 51) background color
                Color BorderColor = Color.FromArgb(51, 102, 153); // blue ( 51, 102, 153 ) border color
                e.Graphics.FillRectangle(ItemColor, e.Bounds.X, e.Bounds.Y, (float)210, e.Bounds.Height - 1); // active border
                e.Graphics.DrawRectangle(new Pen(BorderColor), e.Bounds.X, e.Bounds.Y, (float)209, e.Bounds.Height - 1); // normal border
            }
            Bitmap MyIcon = global::Soulwell___Realmlist_modifer.Properties.Resources.off;
            e.Graphics.DrawImage(MyIcon, e.Bounds.Left + 190, e.Bounds.Top + 8, 10, 10);
            MyIcon.Dispose();
            e.DrawText();
        }

Tam jsem se zkoušel nacpat různé podmínky a cykly, ale když už to fungovalo tak to bylo strašně nepraktické protože celý listview mi blinkal. xD
Moje otázka zní : " Šla by udělat nějaká metoda, která v pozadí počká a až podle toho, jestli zjistí zda je server online / offline použije nějak ten drawitem"? Aby se to vlastně nedělo pořád? Tak doufám že si na mě někdo udělá čas protože já už jedu na výpary. xD

Celý projekt zde -> https://github.com/…list-changer
TCP -> https://github.com/…r/TCPtest.cs
Main -> https://github.com/…/MainForm.cs

Předem dím za každou informaci :) Tomáš

Editováno 20.1.2013 23:22
Odpovědět
20.1.2013 23:21
Коммунизм для нашего будущего!
Avatar
Luboš Běhounek Satik:20.1.2013 23:45

Já bych to řešil asi tak, že bych si udělal pole stavů serverů.

Při vykreslení bys vykreslil ikonku podle stavu serveru, který je uložen v tom poli.

Pingání/připojování na servery pokaždý strč do vlastního vlákna a akorát na konci uprav tu informaci v tom poli stavů.

Nezapomeň, že když do něčeho přistupuješ z víc vláken (pole stavů serverů), musíš to nějak ošetřit - tady třeba přes konstrukci lock.

Nahoru Odpovědět
20.1.2013 23:45
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Зайчик:20.1.2013 23:54

Promiň, ale to mi jako moc dobrý nápad nepřijde. Protože než se všechny hodnoty nasypou do pole tak DrawItem už dávno jede. A pak to bude pořád akorát blikat, já bych potřeboval nějakou metodu, která by upravila jen ty obrázky, text a rámeček nechat tak, jak je. :)

Nahoru Odpovědět
20.1.2013 23:54
Коммунизм для нашего будущего!
Avatar
Odpovídá na Зайчик
Luboš Běhounek Satik:21.1.2013 0:46

Asi jsi mě nepochopil :) .
Zezačátku v tom poli máš uložený třeba hodnoty, že se stav zjišťuje.
Když se mají refreshnout pingy, tak zavoláš nějakou funkci, která (podle typu) pro každej server spustí nový vlákno, který zjistí stav a hned po doběhnutí uloží výsledek do toho pole, takže vlastně zjišťuješ stav všech serverů najednou (ne postupně, jak jsi to asi pochopil) a nezakousneš tím hlavní vlákno.

A bliká to už teď, není důvod, proč by to pak mělo blikat víc, problém je nejspíš špatná implementace překreslování.
Zbavíš se toho třeba tak, že si přepíšeš třídu ListView:

class ListViewFixed : System.Windows.Forms.ListView
{
    public ListViewFixed()
    {
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.EnableNotifyMessage, true);
    }

    protected override void OnNotifyMessage(Message m)
    {
        if(m.Msg != 0x14)
        {
            base.OnNotifyMessage(m);
        }
    }
}
Editováno 21.1.2013 0:49
Nahoru Odpovědět
21.1.2013 0:46
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Зайчик:21.1.2013 16:47

To mi vůbec na to blikání nepomohlo xD to bude spíš tím že ten DrawItem jede pořád v kuse ne? Že to bliká jen když po tom rychle jezdím myší tak problikne ten text xD už mě to fakt nebaví normální listview byl parádní a člověk tam chce mít jinej rámeček než defaultní modrý od windowsu a hned takové starosti s tím x(

Nahoru Odpovědět
21.1.2013 16:47
Коммунизм для нашего будущего!
Avatar
Odpovídá na Зайчик
Luboš Běhounek Satik:21.1.2013 17:02

Blikání by mělo zmizet, pošli, jak to teď máš.
Přinejhorším použij PictureBox a kresli si to sám, pak to blikat nebude :D

Bliká to proto, že při překreslení se se vykreslí celý pozadí a pak ten item a nejspíš mezi každým tím kreslením se to překreslí i na obrazovku (ne jen do nějakýho bufferu).

Nahoru Odpovědět
21.1.2013 17:02
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Зайчик:21.1.2013 17:13

no mám to takhle nic moc sem neměnil akorát jsem tam hodil aby se mi vykresloval text manuálně a ne přes e.drawtext();

private void ServerList_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            string status = e.Item.Text;
            Brush textColor = Brushes.Black;
            if (e.Item.Selected == true)
            {
                ServerList.ForeColor = Color.FromArgb(50, 146, 242); // blue text color
                SolidBrush ItemColor = new SolidBrush(Color.FromArgb(51, 51, 51)); // gray ( 51, 51, 51) background color
                Color BorderColor = Color.FromArgb(51, 102, 153); // blue ( 51, 102, 153 ) border color
                e.Graphics.FillRectangle(ItemColor, e.Bounds.X, e.Bounds.Y, (float)210, e.Bounds.Height - 1); // active border
                e.Graphics.DrawRectangle(new Pen(BorderColor), e.Bounds.X, e.Bounds.Y, (float)209, e.Bounds.Height - 1); // normal border
            }
            else
            {
                //e.DrawText();
            }
            Bitmap MyIcon = global::Soulwell___Realmlist_modifer.Properties.Resources.off;
            e.Graphics.DrawImage(MyIcon, e.Bounds.Left + 190, e.Bounds.Top + 8, 10, 10);
            MyIcon.Dispose();
            e.Graphics.DrawString(status, e.Item.Font, textColor, e.Bounds.Left + 2 + 40, e.Bounds.Top + 1);
        }

a přidal jsem tam ještě to upravení třídy jak si říkal

class ListViewFixed : System.Windows.Forms.ListView
{
    public ListViewFixed()
    {
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.EnableNotifyMessage, true);
    }

    protected override void OnNotifyMessage(Message m)
    {
        if(m.Msg != 0x14)
        {
            base.OnNotifyMessage(m);
        }
    }
}
Nahoru Odpovědět
21.1.2013 17:13
Коммунизм для нашего будущего!
Avatar
Luboš Běhounek Satik:21.1.2013 17:30

Na githubu mas aktualni verzi?

Editováno 21.1.2013 17:30
Nahoru Odpovědět
21.1.2013 17:30
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Nahoru Odpovědět
21.1.2013 17:33
Коммунизм для нашего будущего!
Avatar
Odpovídá na Зайчик
Luboš Běhounek Satik:21.1.2013 17:34

Ze tam ten listview upravenej nikde nevidim :\

Nahoru Odpovědět
21.1.2013 17:34
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Зайчик:21.1.2013 17:43

už to tam je jsem to prdnul do třídy ListViewFixed

Nahoru Odpovědět
21.1.2013 17:43
Коммунизм для нашего будущего!
Avatar
Luboš Běhounek Satik:21.1.2013 17:54

Nestačí tam jen nadefinovat tu třídu ListViewFixed a nechat ji tam ležet, musíš ji taky použít - ten tvuj seznam serverů musí bejt typu ListViewFixed a ne ListView :)

Nahoru Odpovědět
21.1.2013 17:54
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Зайчик:21.1.2013 18:15

Dík, zdá se že už to nebliká. Pomohl bys mi ještě s tím jak změnit obrázek pomocí toho tcp připojení? :[

Nahoru Odpovědět
21.1.2013 18:15
Коммунизм для нашего будущего!
Avatar
Odpovídá na Зайчик
Luboš Běhounek Satik:21.1.2013 18:46

Jestli to dobře chápu, tak ten obrázek kreslíš v metodě DrawItem.

Vlastně si všechny ty věci můžeš napsat do ListViewFixed - tam bych si udělal třeba Dictionary stavů serverů a ten akorát v tý metodě DrawItem pak podle toho vykreslíš.
Když nějakej server odeber, tak ho taky odebereš, když ho přidá, tak ho přidáš a stav zatím třeba nastavíš na "zjišťuji".

A pak jen v té metodě DrawItem vykreslíš obrázek podle odpovídajícího záznamu v té kolekci.

Když spouštíš v novém vlákně nějakou tu metodu, co zjišťuje dostupnost, tak jí jen ještě předáš jako další parametr tu kolekci stavů a jen změníš stav toho jednoho serveru v té kolekci, až ho budeš vědět.

Nezapomeň to čtení/zapisování do té kolekce hodit do locku.

Nahoru Odpovědět
21.1.2013 18:46
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Зайчик:21.1.2013 19:35

dostal jsem nápad a vyřešil jsem to tak že jsem jen načítal soubory...kde bude uložený počet MS a podle toho vykreslí obrázky...

private void ServerList_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            Bitmap MyIcon = global::Soulwell___Realmlist_modifer.Properties.Resources.off;
            if (e.Item.Selected == true)
            {
                ServerList.ForeColor = Color.FromArgb(50, 146, 242); // blue text color
                SolidBrush ItemColor = new SolidBrush(Color.FromArgb(51, 51, 51)); // gray ( 51, 51, 51) background color
                Color BorderColor = Color.FromArgb(51, 102, 153); // blue ( 51, 102, 153 ) border color
                e.Graphics.FillRectangle(ItemColor, e.Bounds.X, e.Bounds.Y, (float)210, e.Bounds.Height - 1); // active border
                e.Graphics.DrawRectangle(new Pen(BorderColor), e.Bounds.X, e.Bounds.Y, (float)209, e.Bounds.Height - 1); // normal border
                e.DrawText();
            }
            else
                e.DrawText();
            fl.LoadMyFile(ServersDir + e.Item.Text + Suffix, out Help[4]);
            string[] rozdel = Help[4].Split(';');
            if (rozdel[5] != "0")
            {
                mss.Text = rozdel[5];
                MyIcon = global::Soulwell___Realmlist_modifer.Properties.Resources.on;
            }
            else
                mss.Text = "0 ms";
            e.Graphics.DrawImage(MyIcon, e.Bounds.Left + 190, e.Bounds.Top + 8, 10, 10);
            MyIcon.Dispose();
            //e.Graphics.DrawString(status, e.Item.Font, textColor, e.Bounds.Left + 2 + 40, e.Bounds.Top + 1);
        }

A teď jsem v TCP upravím že až se to vykoná zapíše to počet MS do souboru kde to bude drawitem číst :)) myslím že docela dobrý nápad a moc díky za pomoc.

Nahoru Odpovědět
21.1.2013 19:35
Коммунизм для нашего будущего!
Avatar
Odpovídá na Зайчик
Luboš Běhounek Satik:21.1.2013 19:43

Uh, proc tak slozite, proc to zapisujes do souboru? :D

Jen si to uloz do nejakyho seznamu, kterej pri vykresleni prectes.. :D

I kdyby sis mel treba udelat u ListViewFixed staticky List, tak je to porad lepsi nez soubor :)

Nahoru Odpovědět
21.1.2013 19:43
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Зайчик:21.1.2013 19:54

když ono chvíli trvá než to ten TCP zjistí :D a tak dlouho čekat nemůžu :D už to někde musí být a příležitostně když budu potřebovat si to aktualizuju :[

Nahoru Odpovědět
21.1.2013 19:54
Коммунизм для нашего будущего!
Avatar
Luboš Běhounek Satik:21.1.2013 20:00

Jaký čekání pořád, vždyť to zjišťování, jestli se tcp připojí děláš v jiným vlákně, tak ti aplikace nijak nezamrzne :)

A hlavně při každým překreslení načítat data ze souboru je nehorázná prasárna :)

Popiš mi, který čekání přesně máš na mysli :)

Editováno 21.1.2013 20:03
Nahoru Odpovědět
21.1.2013 20:00
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Зайчик:21.1.2013 20:16

čekání na to vlákno... jestli bude true nebo false xD a pac to bude projizdet prázdný pole :D každopádně teď už to pinguje a funguje jak má :D já bych to nazval úspěšnou prasárnou :(

Nahoru Odpovědět
21.1.2013 20:16
Коммунизм для нашего будущего!
Avatar
Odpovídá na Зайчик
Luboš Běhounek Satik:21.1.2013 20:22

A mit tam ze zacatku par milisekund (prinejhorsim i sekund) stav "zjistuje se" by neslo? :)

Nahoru Odpovědět
21.1.2013 20:22
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Зайчик:21.1.2013 20:26

šlo ale ty servery jsou udělaný dynamicky takže bych si to pole musel různě roztahovat a mazat aby tam byl pořád ten aktuální počet mě teda tohle příjde jako dobrý řešení ( těch serverů nebude milion aby to nějakým způsobem ohrozilo chod aplikace )

Nahoru Odpovědět
21.1.2013 20:26
Коммунизм для нашего будущего!
Avatar
Odpovídá na Зайчик
Luboš Běhounek Satik:21.1.2013 20:30

A přidat si teda tu hodnotu k serverům by nešlo? :)

Nahoru Odpovědět
21.1.2013 20:30
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Зайчик:21.1.2013 20:37

já vím jak to myslíš no :) důležitý je, že už to funguje :) teď je podle mě jedno jestli to je přes pole nebo přes soubory takže až teď fixnu případné chybky můžu samozřejmě předělat :)

Nahoru Odpovědět
21.1.2013 20:37
Коммунизм для нашего будущего!
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Зайчик:21.1.2013 20:39

Každopádně velké díky za pomoc :P :[

Nahoru Odpovědět
21.1.2013 20:39
Коммунизм для нашего будущего!
Avatar
Odpovídá na Зайчик
Luboš Běhounek Satik:21.1.2013 20:42

No, předávat si hodnotu souborem, když si ji můžeš předávat uvnitř programu mi příjde jako větší prasárna, než třeba použití příkazu goto :D

Nahoru Odpovědět
21.1.2013 20:42
https://www.facebook.com/peasantsandcastles/
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
Зайчик:21.1.2013 22:49

jj to máš recht, pak to předělám důležitý je že to funguje prozatím :P každopádně potřeboval bych vědět poslední věc :) kdybys mě navedl správným směrem byl bych ti vděčný :P když kliknu mimo item (text) tak nemám vlastně selectnuto nic, potřeboval bych to nějak udělat aby mi to jako item(text) bralo celý řádek a ne jenom text... nevíš jak na to? Nějakou mě neznámou metodičku? :) Asi jsi už poznal že drawitem používám poprvé :[ předem díky za radu :)

Nahoru Odpovědět
21.1.2013 22:49
Коммунизм для нашего будущего!
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 26 zpráv z 26.