Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.05.2010, 16:05   #1
LLenich
Новичок
Джуниор
 
Регистрация: 06.05.2010
Сообщений: 2
По умолчанию работа с Windows Form

Здравствуйте.
Подскажите, пожалуйста,...
Я создаю приложение в Visual Studio C++ 2008 и столкнулся со следующей

проблеммой: мое приложение работает с Windows Form (CLR-приложение), после

того, как я запущу приложение, оно выполняет определенный код, который

занимает некоторое время, на форме расположены индикаторы выполнения кода

(такие скажем, как ProgressBar), все они нормально работают и все

отображают, если я ее не трогаю, и она активна, но если я переключаюсь на

другие приложения или, скажем, пытаюсь использовать какие-либо элементы

управления, которые есть на форме, то моя форма становится белого цвета, и

появляется всем известная надпись: "приложение не отвечает". Оно не отвечает

до того момента, пока не выполнится код.
Главная форма в процессе работы вызывает другую форму (не в модальном

режиме), которая в свою очередь и выполняет основной код, на кот. и

расположены необходимые элементы управления, виснут обе формы.
Я ставил такой оператор в исполняемом цикле:
testDialog->Refresh();
где testDialog - есть побочная форма, но это не помогло.
Скажите, пожалуйста, как сделать так, чтобы были доступны элементы

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

Извините, если сложно написал...
LLenich вне форума Ответить с цитированием
Старый 06.05.2010, 16:54   #2
Hollander
Участник клуба
 
Аватар для Hollander
 
Регистрация: 03.05.2007
Сообщений: 1,189
По умолчанию

Используй потоки.
Hollander вне форума Ответить с цитированием
Старый 07.05.2010, 23:55   #3
Kottik
Пользователь
 
Регистрация: 19.08.2009
Сообщений: 47
По умолчанию

Решение без отдельного потока

Windows Forms приложения работают на основе так называемых ‘сообщений’, которые накапливаясь, помещаются в ‘очередь сообщений’ потока, клики мышью – это тоже сообщения, которые должны быть соответствующим образом обработаны. В приведенном случае, когда выполняется продолжительный код – новые сообщения не могут обрабатываться по причине того, что еще не завершил свою работу текущий обработчик, т. е. любые сообщения от мыши, клавиатуры, перерисовки и т. д. в момент обработки текущего сообщения не обрабатываются, что особенно хорошо заметно на длительных операциях. Чтобы дать возможность обработать сообщения, ожидающие в данный момент в очереди, в длительный цикл/код нужно вставить вызов метода Application.DoEvents().

Пример:
Цитата:
В моем приложении есть метод, вызываемый по нажатию на кнопку, и заполняющий ListBox большим кол-вом элементов (несколько тысяч), что происходит довольно долго, поэтому я предусмотрел кнопку для отмены заполнения, но она не нажимается во время заполнения ListBox’a, как это исправить не создавая дополнительного потока?
Код:
class DoEventsDemo : Form
{
    bool isCancel;
    Button btStart, btCancel;
    ListBox lbTest;
    Label lblCounter;
    public DoEventsDemo()
    {
        btStart = new Button();
        btStart.Click += new EventHandler(OnButtonStartClick);
        btStart.Text = "&Start"; btCancel = new Button();
        btCancel.Top = btStart.Bottom;
        btCancel.Click += new EventHandler(OnButtonCancelClick);
        btCancel.Text = "&Cancel"; lbTest = new ListBox();
        lbTest.Top = btCancel.Bottom; lblCounter = new Label();
        lblCounter.Top = lbTest.Bottom; Controls.AddRange(new Control[] { btStart, btCancel, lbTest, lblCounter });
    }
    void OnButtonStartClick(object sender, EventArgs e)
    {
        ((Control)sender).Capture = false;
        isCancel = false;
        lbTest.Items.Clear();
        for (int i = 0; i < 20000; i++)
        {
            if (isCancel)
                return; 
            lbTest.Items.Add(i);
            lblCounter.Text = i.ToString();
            //************* Вот он - вызов DoEvents ***********************
            Application.DoEvents();
            //********************************************************
        }
    }
    void OnButtonCancelClick(object sender, EventArgs e)
    {
        isCancel = true;
    }

    static void Main()
    {
        Application.Run(new DoEventsDemo());
    }
}
Взято отсюда.
Использую сам


WindowsFormsApplicationBase.DoEvent s - метод
Цитата:
Обрабатывает все сообщения Windows, которые в данный момент находятся в очереди сообщений.
Синтаксис:
С++:
Код:
public:
void DoEvents()
Учиться никогда не поздно

Последний раз редактировалось Kottik; 08.05.2010 в 00:18.
Kottik вне форума Ответить с цитированием
Старый 10.05.2010, 12:09   #4
LLenich
Новичок
Джуниор
 
Регистрация: 06.05.2010
Сообщений: 2
По умолчанию

Гениально! Спасибо, Kottik!
LLenich вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Требуется программист C# Windows Form rvn Фриланс 5 13.03.2011 15:33
Книга по Windows Form Application Skynet91 Общие вопросы C/C++ 0 20.03.2010 08:51
C# Windows Form rvn Фриланс 4 26.01.2010 04:23
рисование астроиды (VC++ windows form aplication) vo_sa Общие вопросы C/C++ 1 23.11.2009 00:48