Ru-MaNGOS

Ru-MaNGOS (http://mangos.ytdb.ru/index.php)
-   Языки программирования (http://mangos.ytdb.ru/forumdisplay.php?f=34)
-   -   Функции в С++ (http://mangos.ytdb.ru/showthread.php?t=5256)

partizanes 29.06.2012 16:50

Подскажите как в данном примере получать brSize = e->BytesReceived; раз в секунду
весь пример попытка получить скорость скачивания;
Код:

_WebClient->DownloadFileCompleted += gcnew AsyncCompletedEventHandler(this, &Form1::_DownloadFileCompleted);
_WebClient->DownloadProgressChanged += gcnew System::Net::DownloadProgressChangedEventHandler(this, &Form1::_DownloadProgressChanged);
_WebClient->DownloadFileAsync(gcnew Uri(_URL), _SaveAs);


тут срабатывает постоянно поэтому значение brSize не раз в секунду как нам надо.
Код:

void Form1::_DownloadProgressChanged(System::Object ^sender, System::Net::DownloadProgressChangedEventArgs ^e)
{
    brSize = e->BytesReceived;
        brSizeLast = brSize - brSizeLast;
        Int64 tbtrSize = e->TotalBytesToReceive;
        Int64 ProgressPercentage = brSize * 100 / (tbtrSize);

        String^ drawString = Convert::ToString(ProgressPercentage) + "%"+Convert::ToString(diff);
        System::Drawing::Font^ drawFont = gcnew System::Drawing::Font( "Arial",8.25 );
        SolidBrush^ drawBrush = gcnew SolidBrush( Color::Black );
        PointF drawPoint = PointF(324/2 - 10, 23 / 2 - 7);

        progressBar1->Refresh();
        progressBar1->CreateGraphics()->DrawString( drawString, drawFont, drawBrush, drawPoint );
        progressBar1->Value = e->ProgressPercentage;
}

функция на таймере раз в 1сек срабатывает
Код:

void Form1::dSpeed(System::Object^  sender, System::EventArgs^  e)
{
        Int64 diff = (brSize-brSizeLast)/1024;
}

p.s переменные обьявлены глобально
Код:

Int64 brSizeLast = 0;
INT64 brSize = 0;
Int64 diff = 0;

вся функция откуда что вызывается

rsa 29.06.2012 17:34

ставите блокировки в метод счетчика и метод таймера а в таймере под блокировкой перебрасываете значения из счетчика в какой-то глобал и обнуляете счетчик. и естессно пускаете их в разных нитях.

TOM_RUS 29.06.2012 18:26

Не проще объем скачанного разделить на время прошедшее с начала скачивания? Получите среднюю скорость скачивания.

На C# пример:

Код:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Net;
using System.Windows.Forms;

namespace WinFormsDownloadFileSpeed
{
    public partial class Form1 : Form
    {
        private WebClient Client = new WebClient();

        private string url = "http://snapshot.opera.com/windows/1986_12.01-1491/Opera-Next-12.01-1491.i386.exe";

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Client.DownloadFileCompleted += new AsyncCompletedEventHandler(Client_DownloadFileCompleted);
            Client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Client_DownloadProgressChanged);
            Client.DownloadFileAsync(new Uri(url), "temp.file", DateTime.Now);
        }

        void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            DateTime startTime = (DateTime)e.UserState;

            double speed = (e.BytesReceived / 1024) / (DateTime.Now - startTime).TotalSeconds;

            string text = String.Format("Speed: {0:F3} KB/sec", speed);
            PointF drawPoint = new PointF(progressBar1.Width / 2 - 40, progressBar1.Height / 2 - 7);

            progressBar1.Refresh();
            progressBar1.CreateGraphics().DrawString(text, SystemFonts.DefaultFont, Brushes.Black, drawPoint);
            progressBar1.Value = e.ProgressPercentage;
        }

        void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            MessageBox.Show("Downloaded!");
        }
    }
}


partizanes 29.06.2012 20:22

Код:

void Form1::_DownloadProgressChanged(System::Object ^sender, System::Net::DownloadProgressChangedEventArgs ^e)
{
    DateTime startTime = static_cast<DateTime>(e->UserState);

    Int64 brSize = e->BytesReceived;
        Int64 tbtrSize = e->TotalBytesToReceive;
        Int64 ProgressPercentage = brSize * 100 / (tbtrSize);

        Int32 speed = (brSize / 1024) / (DateTime::Now - startTime).TotalSeconds;

        String^ drawString = Convert::ToString(ProgressPercentage) + "% Speed:"+Convert::ToString(speed)+" Кб/с";
        System::Drawing::Font^ drawFont = gcnew System::Drawing::Font( "Arial",8.25 );
        SolidBrush^ drawBrush = gcnew SolidBrush( Color::Black );
        PointF drawPoint = PointF(324/2 - 10, 23 / 2 - 7);

        progressBar1->Refresh();
        progressBar1->Value = e->ProgressPercentage;
        progressBar1->CreateGraphics()->DrawString( drawString, drawFont, drawBrush, drawPoint );
       
}

работает ,но мерцает , периодически исчезает текст и появляется через пол секунды .

сложные расчеты?backgroundworker?

add глючит на вин7
на 2003 не глючит;



debug намекает что строчка пропадает при

Код:

        while(_WebClient->IsBusy)
        {
                Application::DoEvents();
        }

Добавлено через 1 час 7 минут
перенес
Код:

        while(_WebClient->IsBusy)
        {
                String^ drawString = Convert::ToString(ProgressPercentage) + "% Speed:"+Convert::ToString(speed)+" Кб/с";
                System::Drawing::Font^ drawFont = gcnew System::Drawing::Font( "Arial",8.25 );
                SolidBrush^ drawBrush = gcnew SolidBrush( Color::Black );
                PointF drawPoint = PointF(324/2 - 10, 23 / 2 - 7);
                progressBar1->CreateGraphics()->DrawString( drawString, drawFont, drawBrush, drawPoint );
                Application::DoEvents();
        }

перестало мигать

Код:

void Form1::_DownloadProgressChanged(System::Object ^sender, System::Net::DownloadProgressChangedEventArgs ^e)
{
    DateTime startTime = static_cast<DateTime>(e->UserState);

    Int64 brSize = e->BytesReceived;
        Int64 tbtrSize = e->TotalBytesToReceive;
        ProgressPercentage = brSize * 100 / (tbtrSize);

          speed = (brSize / 1024) / (DateTime::Now - startTime).TotalSeconds;

        progressBar1->Refresh();
        progressBar1->Value = e->ProgressPercentage;
       
}


TOM_RUS 29.06.2012 20:42

Вложений: 1
Можно просто создать свой кастомный прогресс бар.

partizanes 29.06.2012 20:57

в моей программе после
_WebClient->DownloadFileAsync(gcnew Uri(_URL), _SaveAs, DateTime::Now);
следущий код
Код:

String^ Form1::getMD5Stream(String^ fileName)
{
        FileStream^ fs = File::OpenRead( fileName );
...

поэтому приходиться использовать
Код:

Application::DoEvents();
сразу после
Код:

DownloadFileAsync
из за этого все проблемы с мерцанием.

Спасибо за подсказку и вообщем то готовый код.

TOM_RUS 29.06.2012 21:57

Тогда можно вызвать getMD5Stream() из DownloadFileCompleted() чтобы избавится от Application::DoEvents()...

partizanes 29.06.2012 22:30

кажется если убрать getMD5Stream() отсюда код который дальше просто продолжит выполнение;

Видимо придется переписывать :mda:
сама реализация такая .
красным выделил вызовы функций;
PHP код:

void Form1::DownloadInstall() 


а тут в самом конце вызов DownloadInstall и установка

TOM_RUS 29.06.2012 23:47

Не проще создать инсталятор для всего этого?

File->New Project->Other Project Files->Setup and Deployment->Visual Studio Installer->Setup Project...

http://msdn.microsoft.com/en-us/library/206sadcd

partizanes 30.06.2012 00:10


partizanes 13.08.2012 18:13

Доброго времени суток!

Подскажите ,столкнулся с фризом при использовании коннектора:
случай 1:
не доходим до блока finally
Код:

        try
        {
                conn->Open();
                return true;
        }

        catch (Exception^ exc)
        {
                return false;
        }

        finally
        {
                if (reader != nullptr)
                        reader->Close();
        }

исправлял так :

Код:

        try
        {
                conn->Open();
                par = true;
        }

        catch (Exception^ exc)
        {
                MessageBox::Show("Exception: " + exc->Message);
                par = false;
        }

        finally
        {
                if (reader != nullptr)
                        reader->Close();
        }

        return par;

проблема решена ;
теперь собственно вопрос:

есть функция которая делает запрос в базу:
блок чтения;
Код:

                while(reader->Read())
                {
                        check_turn(reader->GetString(0),reader->GetString(1),reader->GetDateTime(2));
                }

в функции check_turn
Код:

                while(reader->Read())
                {
                        //THIS NEED CHECK FOR NULL
                        sale = reader->GetString(0);
                }

получается мы имеем не закрытое соединение ?

p.s под фризом я имел ввиду в момент первого вызова фукнции ,приложения виснет от 3-10 секунд,даже бывает вываливается в таймаут . Последующие вызовы проходят мгновенно.


кхм пересмотрел всю свою писаннину и наверно понял что не в одном блоке финали не закрываю соединение

Код:

conn->Close();
правильно наверно так делать
Код:

                if(conn->State  == ConnectionState::Open)
                        conn->Close();


partizanes 14.11.2012 22:11

Код:

char buf[5];

GetPrivateProfileString("SETTINGS", "start_check","true",buf,sizeof(buf),SystemStringToChar(Environment::CurrentDirectory+"\\config.ini"));

if(CharToSystemString(buf) != "true")
        return;

подскажите как правильно проверять полученные bool значения из конфига?(или проверка строка == строка тоже возможна и не считается дурным тоном)
и как можно удалить всю информацию из массива,допустим что бы повторно запросить информацию из конфига о другом параметре в тот же массив;

TOM_RUS 16.11.2012 22:59

А почему ini? Это же устаревший формат. Можно легко заменить на XML и использовать сериализацию. А если бы писали на C#, то вообще можно было бы использовать встроеную функцию Application Settings...

Я у себя в одной тулзе использовал что-то типа этого:
C#
Код:

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

namespace stream.status
{
    [XmlRootAttribute("Config", Namespace = "")]
    public class Config
    {
        private const string FileName = "streams.xml";

        public bool Speech { get; set; }
        public bool OnlineOnly { get; set; }
        public int Interval { get; set; }

        // список стримов
        public readonly List<StreamInfo> Streams = new List<StreamInfo>();

        private static XmlSerializer Serializer = new XmlSerializer(typeof(Config), /*extra types*/ new Type[] { typeof(StreamInfo) });

        private static Config instance;

        private Config() { }

        /// <summary>
        /// Creates empty config with default settings
        /// </summary>
        private static void Init()
        {
            using (var fs = new FileStream(FileName, FileMode.Create))
            {
                Serializer.Serialize(fs, new Config());
            }
        }

        /// <summary>
        /// Saves current settings to a file
        /// </summary>
        public void Save()
        {
            using (var fs = new FileStream(FileName, FileMode.Create))
            {
                Serializer.Serialize(fs, instance);
            }
        }

        public static Config Instance
        {
            get
            {
                if (instance == null)
                {
                    if (!File.Exists(FileName))
                        Init();

                    using (var fs = new FileStream(FileName, FileMode.Open))
                    {
                        instance = (Config)Serializer.Deserialize(fs);
                    }
                }

                return instance;
            }
        }
    }
}

C++/CLI
Код:

#pragma once

using namespace System;
using namespace System::Collections::Generic;
using namespace System::IO;
using namespace System::Xml::Serialization;

public ref class StreamInfo
{
    public:
        StreamInfo() {}

        [XmlAttribute]
        Int32 TestValue;
};

[XmlRoot("Config", Namespace="")]
public ref class Config
{
    // Methods
    private:
        Config()
        {
            Streams = gcnew List<StreamInfo^>();
        }

        static void Init()
        {
            FileStream ^ fs = nullptr;
            try
            {
                fs = gcnew FileStream(FileName, FileMode::Create);
                Config::Serializer->Serialize(fs, gcnew Config());
            }
            finally
            {
                if(fs != nullptr)
                    delete fs;
            }
        }

    public:
        void Save()
        {
            FileStream ^ fs = nullptr;
            try
            {
                fs = gcnew FileStream(FileName, FileMode::Create);
                Config::Serializer->Serialize(fs, Config::instance);
            }
            finally
            {
                if(fs != nullptr)
                    delete fs;
            }
        }

    // Properties
    public:
        property static Config ^ Instance
        {
            Config ^ get()
            {
                if (Config::instance == nullptr)
                {
                    if (!File::Exists(FileName))
                    {
                        Config::Init();
                    }

                    FileStream ^ fs = nullptr;
                    try
                    {
                        fs = gcnew FileStream(FileName, FileMode::Open);
                        Config::instance = (Config^)(Config::Serializer->Deserialize(fs));
                    }
                    finally
                    {
                        if(fs != nullptr)
                            delete fs;
                    }
                }
                return Config::instance;
            }
        }

        property Int32 Interval
        {
            Int32 get()
            {
                return _interval;
            }
            void set(Int32 val)
            {
                _interval = val;
            }
        }

        property Boolean OnlineOnly
        {
            Boolean get()
            {
                return _onlineOnly;
            }
            void set(Boolean val)
            {
                _onlineOnly = val;
            }
        }

        property Boolean Speech
        {
            Boolean get()
            {
                return _speech;
            }
            void set(Boolean val)
            {
                _speech = val;
            }
        }

    // Fields
    private:
        literal String ^ FileName = "streams.xml";
        static Config ^ instance;
        static initonly XmlSerializer ^ Serializer = gcnew XmlSerializer(Config::typeid, gcnew array<Type ^, 1> { StreamInfo::typeid });
        Int32 _interval;
        Boolean _onlineOnly;
        Boolean _speech;
    public:
        initonly List<StreamInfo^> ^ Streams;
};

Использование:
Код:

var streamsCount = Config.Instance.Streams.Count;
...
useSpeechToolStripMenuItem.Checked = Config.Instance.Speech;
...
onlineOnlyToolStripMenuItem.Checked = Config.Instance.OnlineOnly;
...
timer1.Interval = Config.Instance.Interval;
...
Config.Instance.Interval = timer1.Interval;
Config.Instance.Save();
...
Config.Instance.Speech = useSpeechToolStripMenuItem.Checked;
Config.Instance.Save();
...
Config.Instance.OnlineOnly = onlineOnlyToolStripMenuItem.Checked;
Config.Instance.Save();
...
Config.Instance.Streams.Add(new StreamInfo(f.Id, f.StreamName, f.Type));
Config.Instance.Save();

на выходе получается вот такой XML файл:
Код:

<?xml version="1.0"?>
<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Streams>
    <StreamInfo Id="1" Name="Stream 1" Type="Own3d" />
    ...
    <StreamInfo Id="n" Name="Stream n" Type="Justin" />
  </Streams>
  <Speech>true</Speech>
  <OnlineOnly>false</OnlineOnly>
  <Interval>120000</Interval>
</Config>


HuntsMan 24.12.2012 12:19

Извиняюсь за небольшой оффтоп, но не нашел тут подходящей темы, а новую создавать ради такого маленького вопроса не очень хочется. Собственно пытаюсь сделать аналог C# ReadUInt32 на C++.

Код:

    uint32 result = 0;

    for (int i = 0; i < 4; i++)
        result |= *ptr++ << (i * 8);

Верно я мыслю?

Sid 24.12.2012 13:01

ReadUInt32 - откуда читаешь то? Например через reinterpret_cast

Код:

uint32 value = *reinterpret_cast<uint32*>(data);
При условии что data это char* длинной 4 байта.

Или допустим с сокета в Qt я считываю вот так

Код:

read((char*)&value, 4);

HuntsMan 24.12.2012 13:37

const char* ptr;


Текущее время: 15:14. Часовой пояс GMT +3.

ru-mangos.ru - Русское сообщество MaNGOS