Avatar
Зайчик
Člen
Avatar
Зайчик:

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):

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
:)
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
Зайчик:

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):

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
:)
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
Зайчик:

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):

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
:)
Avatar
Зайчик
Člen
Avatar
Зайчик:

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):

Na githubu mas aktualni verzi?

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

Ze tam ten listview upravenej nikde nevidim :\

Nahoru Odpovědět 21.1.2013 17:34
:)
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
Зайчик:

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):

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
:)
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
Зайчик:

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):

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
:)
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
Зайчик:

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):

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
:)
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
Зайчик:

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):

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
:)
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
Зайчик:

č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):

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

Nahoru Odpovědět 21.1.2013 20:22
:)
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
Зайчик:

š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):

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

Nahoru Odpovědět 21.1.2013 20:30
:)
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
Зайчик:

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)
Зайчик:

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):

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  +2 21.1.2013 20:42
:)
Avatar
Зайчик
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
Зайчик:

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.