Как ускорить затемнение области?

Hastings

Добрый день! Никогда не умел правильно формулировать заголовки тем, так что подробнее распишу тут. Значится у меня есть большая квадратная форма. На неё во весь размер я плюхнул панель с какой-то картиночкой на бэкграунде. Я хотел добавить эффект затемнения экрана и потому (может есть способ лучше, но я хз), я добавил поверх панели во всю её площадь пикчер бокс. В этот пикчер бокс у меня заливается от 1 до 100 картиночки с прозрачностью от 1 до 100. Ну и собсна, таким образом, я реализовал затемнение экрана, чтобы потом, например, переходить в другое меню и т.д. и т.п. Каждую новую картинку из этой 100 программа присваивает пикчербоксу из таймера. Я поставил ему самый быстрый такт - 1мс. Т.е. при нажатии на кнопку, запускатеся таймер, всё затемняется, а потом он вырубается, и программа живёт дальше своей жизнью.ВОПРОС!На всех компах скорость затемнения РАЗНАЯ. Тестил на 3 машинах. Шо делать? Я начал думать, что это потому что таймер (если что я на вин формс, да, совсем атсрала питек, я знаю). Типа таймер, как я ДУМАЮ (я же не знаю, потому и спрашиваю у людей добрых совета и знаний), точнее такт таймера зависит от такта процессора. Если это правда, то как отвязаться и сделать моё затемнение адекватным? Если нет, то просто что мне делать? Конечно, если уменьшить окно до размеров ярлыка, то всё чики-пуки, но у меня большое окнище и надо его оставить таким. Может надо что-то с clock делать, чё-нить там выщитывать и типа будет привязка ко времени? Прощу у вас помощи и совета!Я тут ещё подумал... может есть какой-то более быстрый способ присваивания картинок? Или типа того... Я сейчас делаю это так.
String^ pages=Convert::ToString(page);
MenuFading->Image = MenuFading->Image->FromFile("Data\\Cube"+pages+".png");
page++;
Может их надо сначала залить в ресурсы? Или ещё как-то куда-то добавить. Если проблема в этом, то опять же прошу совета куда залить и как именно. Спасибо!
4 ответа

Hastings

Типа таймер, как я ДУМАЮ (я же не знаю, потому и спрашиваю у людей добрых совета и знаний), точнее такт таймера зависит от такта процессора
Ошибочно. Задержка на всех компах будет одинаково для таймера, а вот скорость обработки кода в блоке будет зависть от производительности системы. Для такой анимации вы выбрали совсем не тот подход, во первых слишком ресурсоемкий - закачка в память файла изображения, декодирование, наложение на поверхность, присвоение контролу, + может быть утечка памяти в связи чудной работы мусорщика на .net (с изображениями). Самое простое, по мне, использовать ресурсы gdi. Но там так же придется считаться с производительностью. Я так понимаю, в нужный момент на форму натягивается pictureBox и производит анимацию затемнения?


Hastings

Да. Но вообще он всегда весит этот самый пикчер бокс, просто визибл=фолз


Hastings

Попробуйте так. Сделал затенение заднего фона формы без pictureBox Аналогично делается для других контролов, главное событие "рисования" подписать. Но это работает только с картинкой, а вот, если вам необходимо одновременно все элементы таким образом скрывать, то придется докостыливать
Кликните здесь для просмотра всего текста
        int _colorA = 0x00000000;
        int _colorB = 0xff000000;
        float _ratioBlend = 0.0f;
        SolidBrush ^_curColor = gcnew SolidBrush(Color::FromArgb(_colorA));
        Timer ^_timer;
        const int _timePlay = 500;
        const int _interval = _timePlay / 40;
        const float _step = (float)_interval / (float)_timePlay;
 
        System::Void RunAnimation()
        {
 
            if (_timer == nullptr)
            {
                _timer = gcnew Timer();
                _timer->Interval = _interval;
                _timer->Tick += gcnew EventHandler(this, &MyForm::Animate);
                _timer->Start();
            }
        }
 
        System::Void Animate(System::Object ^sender, System::EventArgs ^e)
        {
 
            _ratioBlend += _step;
 
            if (_ratioBlend > 1.0f)
            {
                _ratioBlend = 1.0f;
                _timer->Stop();
                delete _timer;
                _timer = nullptr;
            }
 
            _curColor->Color = Color::FromArgb(GetBlendColor(_colorA, _colorB, _ratioBlend));
 
            this->Invalidate();
        }
        
        int GetBlendColor(int ColorA, int ColorB, float Ratio /*значения от 0.0f до 1.0f*/)
        {
            Byte *a = (Byte*)&ColorA;
            Byte *b = (Byte*)&ColorB;
            return a[0] + int((b[0] - a[0]) * Ratio) |
                (a[1] + int((b[1] - a[1]) * Ratio)) << 8 |
                (a[2] + int((b[2] - a[2]) * Ratio)) << 16 |
                (a[3] + int((b[3] - a[3]) * Ratio)) << 24;
        }
        
        System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
            this->RunAnimation();
        }
 
        System::Void MyForm_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) // подписка на событие Paint формы
        {
            e->Graphics->FillRectangle(_curColor, e->ClipRectangle);
        }
Запуск с кнопки


Hastings

Спасибо большое, правда пробывать я это даже не буду, ахах) На дня я решил перестать страдать и перешёл на SFML. Бесконечные проблемы и костыли при создании чего-то внятного на winfroms уже изрядно задолбало. Всё равно ещё раз спасибо!